OsakaWebbie
Programmer
I have a structure like this:
Queries for people info almost always join these three tables thus:
If a person is in Japan, their address is not just the Address field, but:
And the romanized writing of their address is:
There are lots of other tables that hinge from PersonID that are often involved in queries as well, and one main search page that combines stuff from almost all the tables and assists with building a variety of WHERE criteria.
Well, I learned today that multiple users using that main search to look for people based on some piece of text being in their address ("WHERE CONCAT(h.PostalCode,pc.Prefecture,pc.ShiKuCho,h.Address) LIKE '%yadayada%') can cripple the server. I got to thinking about it and realized that I should try to figure out how to get an index on that constructed text. I assumed I could make a view that includes those full addresses (which I should have done a long time ago anyway, to simplify my code) and then put an index on them. But apparently views can't have indexes. I could put indexes on the individual fields, but since I always search and/or retrieve them in the concatenated form, would that even help? (Sorry, I don't know how to do performance tests when I'm using a remote VPS.) Does someone have a suggestion as to what I can do to make this kind of query less of a CPU drain?
Code:
CREATE TABLE person (
PersonID int(11) unsigned NOT NULL auto_increment,
FullName varchar(100) NOT NULL default '',
HouseholdID int(11) unsigned NOT NULL default '0',
(...other fields...)
PRIMARY KEY (PersonID),
KEY Furigana (Furigana),
KEY FullName (FullName),
KEY Email (Email),
KEY Organization (Organization,Furigana)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE household (
HouseholdID int(11) unsigned NOT NULL auto_increment,
NonJapan tinyint(1) NOT NULL default '0',
PostalCode varchar(8) NOT NULL default '',
Address varchar(200) NOT NULL default '',
RomajiAddress varchar(200) NOT NULL default '',
(...other fields...)
PRIMARY KEY (HouseholdID)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE postalcode (
PostalCode varchar(8) character set ascii collate ascii_bin NOT NULL default '',
Prefecture varchar(12) NOT NULL default '',
ShiKuCho varchar(54) NOT NULL default '',
Romaji varchar(200) NOT NULL default '',
PRIMARY KEY (PostalCode)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
Code:
SELECT yada, yada from person
LEFT JOIN household ON person.HouseholdID=household.HouseholdID
LEFT JOIN postalcode ON household.PostalCode=postalcode.PostalCode
Code:
CONCAT(h.PostalCode,pc.Prefecture,pc.ShiKuCho,h.Address)
Code:
CONCAT(h.RomajiAddress,' ',pc.Romaji,' ',h.PostalCode)
Well, I learned today that multiple users using that main search to look for people based on some piece of text being in their address ("WHERE CONCAT(h.PostalCode,pc.Prefecture,pc.ShiKuCho,h.Address) LIKE '%yadayada%') can cripple the server. I got to thinking about it and realized that I should try to figure out how to get an index on that constructed text. I assumed I could make a view that includes those full addresses (which I should have done a long time ago anyway, to simplify my code) and then put an index on them. But apparently views can't have indexes. I could put indexes on the individual fields, but since I always search and/or retrieve them in the concatenated form, would that even help? (Sorry, I don't know how to do performance tests when I'm using a remote VPS.) Does someone have a suggestion as to what I can do to make this kind of query less of a CPU drain?