0

私は以下のクエリを持っています:

 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,_Tempo‌​rary_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 ______
4

2 に答える 2

1

たとえば、テーブルフィールドPublishedOnが最適であること(1) indexed your table fieldsを確認してください。詳細については、 http://dev.mysql.com/doc/refman/5.1/en/partitioning-range.htmlを参照し てください。(2) Partition tablepartition by range

于 2012-10-29T08:16:07.167 に答える
0

速度はテーブルインデックスによって異なります。列のインデックスを設定しPublishedOnます。その後、テーブルの最適化も試みてください。

OPTIMIZE TABLE `Article`;
于 2012-10-29T08:35:51.490 に答える