1

SQL の最適化は苦手ですが、このクエリをできるだけ速く実行する必要があります。PHP スクリプトによって、約 40 の異なるデータベースで繰り返し実行されます。次に、PHP は結果を時系列に並べ替えます。

SELECT DATE_FORMAT(lastmoddate, '%a %b %D, %Y  %l:%i%p') as lastmod,
       count(*) as num_modified,
       (select count(*) from store.item) as totalitems,
       UNIX_TIMESTAMP(lastmoddate) as timestamp
FROM store.item
group by lastmoddate
HAVING lastmoddate = MAX(lastmoddate)
order by lastmoddate desc
limit 1;

説明

  • lastmoddateは、アイテム レコードの最終更新日です。
  • count(*) (num_modifiedは最後の更新で変更されたアイテムの数)
  • サブクエリは、テーブル内の合計項目を取得します
  • UNIX_TIMESTAMPはおそらく不要ですが、後で PHP でのソートに使用します。この結果は、他のデータベースからの結果と共にプールされ、ソートされます。

したがって、最終的な目標は、最終変更日、その最終変更日に変更されたアイテムの数、およびデータベース内の合計アイテムを含むテーブルを取得することです。

サブクエリは削除される可能性がありますが、速度にはあまり影響しないようです。その他の結果が必要です。DATE_FORMAT または UNIX_TIMESTAMP が遅い場合、それらを削除できますが、PHP で同じように遅いものに置き換えられます。(私が言ったように、私は SQL の最適化については何もしません。機能するクエリを配置するだけでかなり気分が良くなりました。)

MySQL 5.5 および PHP 5.3

4

2 に答える 2

2

最大 の行に関する情報を取得しようとしていますlastmoddate。クエリは、最後の行を選択してすべてのデータを集計しています。lastmoddate

代わりに、最初にフィルタリングを行い、次に集計を行います。group by出力で1行しか取得していないため、句も必要ありません。

アプローチは、サブクエリ内の最大の最終変更日と合計アイテムを計算することです。これは結合されているため、データをフィルタリングできます。

select DATE_FORMAT(i.lastmoddate, '%a %b %D, %Y  %l:%i%p') as lastmod,
       COUNT(*) as NumModified,
       const.totalitems,
       UNIX_TIMESTAMP(i.lastmoddate) as timestamp
from store.item i cross join
     (select max(lastmoddate) as maxlastmoddate, count(*) as totalitems
     ) const
where i.lastmoddate = const.maxlastmoddate;

にインデックスを付けると、パフォーマンスがさらに向上しますstore.item(lastmoddate)

于 2013-05-16T18:33:24.177 に答える
1

できることの 1 つは、count(*) を 1 回選択し、それをサブクエリとして削除することです。40回実行するループの外に置いてください。

持つ節は必要ですか?それがなくても同じ結果が得られますか?where句に入れることができると思います

WHERE lastmoddate = (select max(lastmoddate) from store.item i2)

lastmoddate にインデックスがあることを確認してください。

于 2013-05-16T18:15:17.173 に答える