2012-02-21 15 views
2

私はAccessからmySQLに変更しました。私は "Veranstaltung"と "Veranstaltung_User"と呼ばれるいくつかのテーブルを持っています。私はすべてのイベント(= Veranstaltung)を取得したいと思っています。mySQLのSQLクエリの最適化

私は、次のなステートメント

Accessで
SELECT VID, Bezeichnung, Datum 
FROM tbl_Veranstaltung 
WHERE year(Datum) = 2012 
    AND VID <> 613 
    AND VID IN (SELECT BewerbID 
       FROM Veranstaltung_User 
       WHERE UserID IN (SELECT UserID 
           FROM Veranstaltung_User 
           WHERE BewerbID = 613) 
        AND UserID <> 0) 
ORDER BY Datum 

でこれをやった、このクエリは非常に高速だった - MySQLではそれが44,56秒を必要とする - 私は最適化する方法が多すぎる;-)

より迅速なクーリングのための声明?助けのための(MySQLの> 5、テーブルはMyISAMテーブルをウェア)

おかげ

答えて

2

2つの変更:
1.用途は
2.代わりにYEAR()機能

<= and >を使用句ではなく、ネストされたJOINを変更1の利点は、いつかINパフォーマンスが予想より悪くなる可能性があり、それらを入れ子にすることはそれを誇張することです。

変更点2の利点は、インデックスシークでレコードの範囲を見つけることができるということです。 Where-YEAR()を使用すると、テーブル全体またはインデックス全体のスキャンが行われます。

どちらも適切なインデックスがあると仮定しています。このクエリは、テーブルレイアウト+へといくつかの仮定を作ってみましたが、調整が必要な場合があり

SELECT 
    V.VID, V.Bezeichnung, V.Datum 
FROM 
    tbl_Veranstaltung  V 
INNER JOIN 
    Veranstaltung_User VUser 
    ON VUser.BewerbID = V.VID 
INNER JOIN 
    Veranstaltung_User VUser2 
    VUser.UserID = VUser2.UserID 
WHERE 
     V.Datum >= '20120101' 
    AND V.Datum < '20130101' 
    AND V.VID <> 613 
    AND VUser.UserID <> 0 
    AND VUser2.BewerbID = 613 
ORDER BY 
    Datum 
+0

次を使用することになりますが、内側に参加「上」逃した - しかし、それは;-) – Stefan

+0

@Stefan作品 - ニーススポットを:) – MatBailie

0

は、私はまた、次の二つの指標に

​​を助言する

SELECT 
    v.VID, 
    v.Bezeichnung, 
    v.Datum 

FROM tbl_Veranstaltung AS v 

INNER JOIN Veranstaltung_User AS vu 
ON vu.BewerbID = v.VID 
AND vu.UserID = [THIS USER ID] 
AND vu.BewerbID <> 613 

// Used a BETWEEN so that MySQL does not need to apply YEAR() to every row 
WHERE v.Datum BETWEEN DATE('2012-01-01') AND DATE('2012-12-30'); 

を提供する任意の明確化に基づいて更新されます

これに続いて、照会は実質的に瞬時に行われるべきである。

編集私はソースクエリがそのまま取れば、私は

SELECT 
    v.VID, 
    v.Bezeichnung, 
    v.Datum 

FROM tbl_Veranstaltung AS v 

INNER JOIN Veranstaltung_User AS vu 
ON vu.BewerbID = v.VID 
AND vu.BewerbID <> 613 
AND vu.UserID <> 0 

WHERE v.Datum BETWEEN DATE('2012-01-01') AND DATE('2012-12-30');