2012-04-09 13 views
1

私は450,000レコードのユーザーテーブルを持っています。テーブル構造はほどです:Mysqlサブクエリの最適化

UserID Int(11) Primary Key 
    Firstname (50) Varchar 
    Lastname (50) Varchar 

私はまた、ユーザーIDは、これらの表にあるかどうかを確認するために他の二つのテーブルをチェックする必要があります。 (構造は少し異なりますが、テーブルのUserIDは同じです) 私はこのサブクエリを以下で実行していますが、非常に遅いです。より高速なビットを実行助けるために新鮮な視点を提供するために、目の第2のセットを感謝...

SELECT 
`Users`.`Firstname`, 
`Users`.`Lastname`, 
`Users`.`UserID` 
FROM `Users` 
WHERE `Users`.`UserID` IN (SELECT `admin`.`UserID` FROM `admin` WHERE `admin`.`UserID`=`User`.`UserID`) 
AND `Users`.`UserID` IN (SELECT `elite`.`UserID` FROM `elite` WHERE `elite`.`UserID`=`Users`.`UserID`) 
AND `Users`.`Lastname` LIKE '%smith%' 
+0

テーブルにはどのようなインデックスがありますか?それぞれのテーブルに対して 'SHOW CREATE TABLE ...'を投稿し、 'EXPLAIN SELECT ... '出力を投稿してください。 –

答えて

2

MySQLでクエリを最適化する際、絶対に最も重要なことは、あなたが適切なインデックスを持っていることを確認することです 。あなたが持っているインデックス(SHOW INDEXを使用して)と、クエリが使用しているインデックス(EXPLAIN SELECTを使用)を確認してください。テーブルが大きくなると、インデックスは良好なパフォーマンスを得るためには絶対に必要不可欠です。

特に、すべての3つのテーブルのUserID列にインデックスがあることを確認する必要があります。私はまた、それがあなたの状況に適している場合は、外国のキー制約を追加することをお勧めします。あなたはすでにあなたが正しいインデックスを持っているとあなたはまだ適切なパフォーマンスを取得されていませんチェックした場合

しかし、あなたが使用して試すことができます代わりに副選択の代わりに参加する:

SELECT 
    Users.Firstname, 
    Users.Lastname, 
    Users.UserID 
FROM Users 
JOIN admin USING (UserID) 
JOIN elite USING (UserID) 
WHERE Users.Lastname LIKE '%smith%' 

LIKE '%smith%'を使用することができないこと効率的なインデックス作成。 LIKE式はできるだけワイルドカードで始まらないようにしてください。

+1

''%smith%''にインデックスを付けることはできません。 – DCoder

+0

@DCoder:追加されました。 –

1

ジョインで開始します。

SELECT 
`Users`.`Firstname`, 
`Users`.`Lastname`, 
`Users`.`UserID` 
FROM `Users` 
INNER JOIN `admin` ON (`Users`.`UserID` = `admin`.`Users`) 
INNER JOIN `elite` ON (`Users`.`UserID` = `elite`.`UserID`) 
WHERE `Users`.`Lastname` LIKE '%smith%' 

インデックスを確認します。

Lastname文字列の先頭または末尾に固定されていないため、姓の検索が遅くなることもあります。

2

サブクエリの代わりに内部結合を使うべきだと思います...今はadminテーブルからユーザーIDを取得していて、エリートテーブルをチェックしていて、それもユーザーテーブルにある必要があるからです。参加してその違いを見てください。

+0

上記のコメントに同意する – Madan