私は以下のクエリを持っています:
SELECT ID FROM
`Article` this_ WHERE
(this_._Temporary_Flag = FALSE OR this_._Temporary_Flag = NULL) AND
this_.Published = TRUE AND
(this_.PublishedOn IS NULL OR this_.PublishedOn <= '2012-10-29 08:54:36') AND
(this_.Deleted = FALSE OR this_.Deleted = NULL) AND
(this_._ComputedDeletedValue = FALSE OR this_._ComputedDeletedValue = NULL) AND
((this_._TestItemSessionGuid IS NULL OR this_._TestItemSessionGuid = '')) AND
NOT (this_.CategoryId IS NULL)
AND (this_.PublishedOn < '2012-09-10 00:00:00' AND this_.CategoryId = 51118080)
ORDER BY this_.PublishedOn DESC LIMIT 1
問題のテーブルには、正確には141,505レコードが含まれています。WHERE
句に記載されているインデックスとすべてのフィールドを確認し、インデックスを作成しましたORDER BY
(インデックスの種類:INDEX、インデックスの種類:BTREE)。
このクエリは、初めて実行するのに40秒かかります。その後の実行は1〜2秒になりますが、これはキャッシングが原因であると想定しています。MySQLサーバーを再起動すると、再び約40秒かかります。パフォーマンスが非常に遅い理由、および実行可能な最適化についてのアイデアはありますか?
アップデート1
データベースはMySQLであり、テーブルストレージエンジンはInnoDbです。
アップデート2
補足として、このクエリの範囲は、現在の記事に関連する「前の記事」を取得することです。PublishedOn
これを行うには、現在の記事よりもフィールドが小さいすべての記事を取得し、PublishedOn
降順で並べ替えて最初の1を取得します(誤ってLIMITを更新したので、最初に50を入力しましたが、1になるはずです)。
他の条件は、有効な記事と同じカテゴリの記事のみをロードすることです。
アップデート3:EXPLAIN出力
SelectType = Select
Type = index_merge
Possible_keys = CategoryId,PublishedOn,_TestItemSessionGuid,Deleted,_ComputedDeletedValue,_Temporary_Flag,Published Key = Deleted,_ComputedDeletedValue,_Temporary_Flag,Published,CategoryId
Key_Len = 1,1,1,1,9
ref = (NULL)
Rows = 3383
Extra = Using intersect(Deleted,_ComputedDeletedValue,_Temporary_Flag,Published,CategoryId); Using where; Using filesort ______