2012-05-03 8 views
0

フォームからデータを取得する次のPHPコードと、完了までに15分かかるMySQLクエリがあります。はるかに速くする必要があります。私は、PHP変数とMySQLクエリを使用するためのベストプラクティスを無視しているのか、クエリ構造自体が許容できないほどの時間がかかるのかどうか、疑問に思っています。PHP変数と非常に遅いMySQLクエリ

質問の基本的な目的は、投票者PKが投票FKとして表示される回数をカウントし、カウントが事前定義された数値(計算に基づく割合)を上回る場合、votersテーブルから対応するレコードを選択することです最終的なPHPの条件文、および2004年以降のすべてをフィルタリングするクエリの部分で行われます)。

投票者テーブルには100万行があり、投票テーブルは700万人ですが、両方のCountyEMSIDキーがインデックスに登録されていますが、テーブル構造を変更することはできません。に。物事をスピードアップする方法に関するアドバイスや提案は、大いに感謝しています!

はまた、エッセイのため申し訳ありません:P

/* ========== GET VALUES ========== */ 
if (isset($_GET["StreetName"])) { $searchStreetName = $_GET["StreetName"]; } else { $searchStreetName = "%"; } 
if (isset($_GET["City"])) { $searchCity = $_GET["City"]; } else { $searchCity = "%"; } 
if (isset($_GET["Zip"])) { $searchZip = $_GET["Zip"]; } else { $searchZip = "%"; } 
if (isset($_GET["DOBY"])) { $searchDOBY = $_GET["DOBY"]; } else { $searchDOBY = "%"; } 
if (isset($_GET["DOBM"])) { $searchDOBM = $_GET["DOBM"]; } else { $searchDOBM = "%"; } 
if (isset($_GET["DOBD"])) { $searchDOBD = $_GET["DOBD"]; } else { $searchDOBD = "%"; } 
if (isset($_GET["Gender"])) { $searchGender = $_GET["Gender"]; } else { $searchGender = "%"; } 
if (isset($_GET["Party"])) { $searchParty = $_GET["Party"]; } else { $searchParty = "%"; } 
if (isset($_GET["ED"])) { $searchED = $_GET["ED"]; } else { $searchED = "%"; } 
if (isset($_GET["AD"])) { $searchAD = $_GET["AD"]; } else { $searchAD = "%"; } 
if (isset($_GET["CD"])) { $searchCD = $_GET["CD"]; } else { $searchCD = "%"; } 
if (isset($_GET["CO"])) { $searchCO = $_GET["CO"]; } else { $searchCO = "%"; } 
if (isset($_GET["SD"])) { $searchSD = $_GET["SD"]; } else { $searchSD = "%"; } 
if (isset($_GET["CC"])) { $searchCC = $_GET["CC"]; } else { $searchCC = "%"; } 
if (isset($_GET["VoterActivity"])) { $searchVoterActivity = (($_GET["VoterActivity"]/100) * 18); } else { $searchVoterActivity = "0"; } 

/* ========== GET DATA ========== */ 
$sql = "SELECT voters.*, COUNT(votes.CountyEMSID) AS 'activity' 
FROM voters INNER JOIN votes ON voters.CountyEMSID = votes.CountyEMSID 
WHERE voters.StreetName LIKE '$searchStreetName%' 
AND voters.City LIKE '$searchCity%' 
AND voters.Zip LIKE '$searchZip%' 
AND voters.DOBY LIKE '%$searchDOBY' 
AND voters.DOBM LIKE '%$searchDOBM' 
AND voters.DOBD LIKE '%$searchDOBD' 
AND voters.Gender LIKE '$searchGender%' 
AND voters.Party LIKE '$searchParty%' 
AND voters.ED LIKE '%$searchED' 
AND voters.AD LIKE '%$searchAD' 
AND voters.CD LIKE '%$searchCD' 
AND voters.CO LIKE '%$searchCO' 
AND voters.SD LIKE '%$searchSD' 
AND voters.CC LIKE '%$searchCC' 
AND votes.ElectionDateY >= 2004 
AND (
votes.ElectionType = 'GE' 
OR votes.ElectionType = 'PR' 
OR votes.ElectionType = 'PP' 
) 
GROUP BY votes.CountyEMSID 
HAVING COUNT(votes.CountyEMSID) >= '$searchVoterActivity' 
ORDER BY voters.LastName, voters.FirstName, voters.DOBY, voters.DOBM, voters.DOBD ASC 
LIMIT $start, $limit"; 

/* ========== CREATE TABLE ========== */ 
CREATE TABLE voters (
    CountyEMSID varchar(9) NOT NULL, 
    LastName varchar(30) NOT NULL, 
    FirstName varchar(30) NOT NULL, 
    MiddleInitial varchar(1) NOT NULL, 
    NameSuffix varchar(4) NOT NULL, 
    HouseNumber varchar(10) NOT NULL, 
    HouseNumberSuffix varchar(10) NOT NULL, 
    ApartmentNumber varchar(15) NOT NULL, 
    StreetName varchar(50) NOT NULL, 
    City varchar(40) NOT NULL, 
    Zip varchar(5) NOT NULL, 
    ZipCode4 varchar(4) NOT NULL, 
    MailingAddress1 varchar(50) NOT NULL, 
    MailingAddress2 varchar(50) NOT NULL, 
    MailingAddress3 varchar(50) NOT NULL, 
    MailingAddress4 varchar(50) NOT NULL, 
    DOBY varchar(4) NOT NULL, 
    DOBM varchar(2) NOT NULL, 
    DOBD varchar(2) NOT NULL, 
    Gender varchar(1) NOT NULL, 
    Party varchar(3) NOT NULL, 
    Other varchar(30) NOT NULL, 
    ED varchar(3) NOT NULL, 
    AD varchar(2) NOT NULL, 
    CD varchar(2) NOT NULL, 
    CO varchar(2) NOT NULL, 
    SD varchar(2) NOT NULL, 
    CC varchar(2) NOT NULL, 
    RegY varchar(4) NOT NULL, 
    RegM varchar(2) NOT NULL, 
    RegD varchar(2) NOT NULL, 
    Status varchar(2) NOT NULL, 
    VoterType varchar(1) NOT NULL, 
    StatusChangeY varchar(4) NOT NULL, 
    StatusChangeM varchar(2) NOT NULL, 
    StatusChangeD varchar(2) NOT NULL, 
    LastVoted varchar(4) NOT NULL, 
    Telephone varchar(12) NOT NULL, 
    KEY CountyEMSID (CountyEMSID) 
) 

/* ========== CREATE TABLE ========== */ 
CREATE TABLE votes (
    CountyEMSID varchar(9) NOT NULL, 
    County varchar(2) NOT NULL, 
    AD varchar(2) NOT NULL, 
    ED varchar(3) NOT NULL, 
    Party varchar(3) NOT NULL, 
    ElectionDateY varchar(4) NOT NULL, 
    ElectionDateM varchar(2) NOT NULL, 
    ElectionDateD varchar(2) NOT NULL, 
    ElectionType varchar(2) NOT NULL, 
    VoterType varchar(1) NOT NULL, 
    KEY CountyEMSID (CountyEMSID) 
) 

答えて

3

は、その顔にシンプルに表示されます:あなたは、インデックスを使用する必要があります。あなたのスキーマダンプには何も見えません。

+0

mysql IRCチャンネルでは、mysqlは一度に1つのインデックスしか使用できないと言われました。私の最善の選択肢は、複合インデックスを左から右の順に検索することです。しかし、私が働いている変数の量がどれほど効果的かは分かりません。このシナリオでインデックスを設定する方法について理解していないことがありますか? EDIT:スキンダンプからインデックスコードを削除してコード混乱を減らしました。私の記事で述べたように、両方のCountyEMSIDキーがインデックスに登録されています。 – deathonater

+0

'郡EMSID'はプライマリキーです。これは非常に基本的なインデックスです。しかし、MySQLは一度に1つのインデックスを使用しますが、インデックスは複雑なものにすることができます。クエリを高速化するには、複数のキーで複合インデックスを実行します。 – buley

+0

アドバイスをいただきありがとうございます!最も一般的に検索される列の3つまたは4つについて複合インデックスを作成しようとします。 – deathonater

関連する問題