0

以下のクエリを最適化する方法はありますか?

SELECT 
DATE_FORMAT(a.duedate,'%d-%b-%y') AS dte, 
duedate, 
SUM(CASE WHEN (typeofnotice='ddat' AND STATUS='open') THEN 1 ELSE 0 END) AS 'DDatOpen', 
SUM(CASE WHEN (typeofnotice='ddat' AND STATUS='closed') THEN 1 ELSE 0 END) AS 'DDatClosed', 
SUM(CASE WHEN (b.action='tagunchanged' AND STATUS='closed') THEN 1 ELSE 0 END) AS 'DDatUnchanged',
SUM(CASE WHEN (typeofnotice='rss' AND validindicator IS NULL AND STATUS='open') THEN 1 ELSE 0 END) AS 'RSSValidation', 
SUM(CASE WHEN (typeofnotice='rss' AND validindicator=1 AND STATUS='open') THEN 1 ELSE 0 END) AS 'RSSValidOpen', 
SUM(CASE WHEN (typeofnotice='rss' AND validindicator=1 AND STATUS='closed') THEN 1 ELSE 0 END) AS 'RSSValidClosed', 
SUM(CASE WHEN (typeofnotice='rss' AND validindicator=0) THEN 1 ELSE 0 END) AS 'RSSInvalid', 
SUM(CASE WHEN (typeofnotice='copernic' AND validindicator IS NULL AND STATUS='open') THEN 1 ELSE 0 END) AS 'CopernicValidation', 
SUM(CASE WHEN (typeofnotice='copernic' AND isaward=1 AND validindicator=1 AND STATUS='open') THEN 1 ELSE 0 END) AS 'CopernicValidAwardOpen', 
SUM(CASE WHEN (typeofnotice='copernic' AND isaward=1 AND validindicator=1 AND STATUS='closed') THEN 1 ELSE 0 END) AS 'CopernicValidAwardClosed', 
SUM(CASE WHEN (typeofnotice='copernic' AND isaward=1 AND validindicator=0) THEN 1 ELSE 0 END) AS 'CopernicInvalidAward', 
SUM(CASE WHEN (typeofnotice='copernic' AND isaward=0 AND validindicator=1 AND STATUS='open') THEN 1 ELSE 0 END) AS 'CopernicOpportunityValidOpen', 
SUM(CASE WHEN (typeofnotice='copernic' AND isaward=0 AND validindicator=1 AND STATUS='closed') THEN 1 ELSE 0 END) AS 'CopernicOpportunityValidClosed', 
SUM(CASE WHEN (typeofnotice='copernic' AND isaward=0 AND validindicator=0) THEN 1 ELSE 0 END) AS 'CopernicOpportunityInvalid', 
SUM(CASE WHEN (typeofnotice='copernic' AND STATUS='limited') THEN 1 ELSE 0 END) AS 'CopernicLimitation', 
SUM(CASE WHEN ((validindicator IS NULL OR validindicator = 1) AND STATUS='open') THEN 1 ELSE 0 END) AS 'TotalNotices', 
SUM(CASE WHEN (validindicator=1 AND STATUS='closed') THEN 1 ELSE 0 END) AS 'TotalCompleted', 
SUM(CASE WHEN (validindicator=0 AND (typeofnotice='wget' OR typeofnotice='copernic' OR typeofnotice='rss')) THEN 1 ELSE 0 END) AS 'TotalInvalid'
FROM tblNotices AS a LEFT JOIN tblTransactions AS b 
ON a.id = b.noticeid WHERE b.noticeid IS NOT NULL
WHERE duedate >= '2011-04-04 00:00:00'  AND  a.duedate <= '2012-05-08 24:00:00' 
GROUP BY dte 
ORDER BY dueDate ASC;

tblTransactions には 150 万行あり、tblNotices には 90 万行あります。

クエリは約 1 分間実行されます。それは正常ですか?このクエリを最適化する方法はありますか?

「テーブル」を説明し、選択を説明する

ここの関数は本当にパフォーマンスを殺していると思いDATE_FORMATます..ここに何かヒントはありますか? 約 58 秒間実行されます。

4

2 に答える 2

1

SUM( IF()) インスタンスを除いて、クエリは可能な限り単純に見えます。

クエリにはトランザクションへの LEFT-JOIN がありますが、b.noticeID が null ではない場所があります。2 つの結果を組み合わせると、両側で必要な通常の「JOIN」または「INNER JOIN」の意味になります。

Where 句については、期日に簡単なインデックスを付けてください。あなたのテーブルは「MUL」(複数キー)インデックスを示しています。期日がそのキーの最初の部分であることを確認するか、少なくとも1つのインデックスが最初のフィールドとして期日を持っています。

次に、グループ化します。期日の日付形式でグループ化を行っているため、期日 (テーブル インデックスに一致する) のみに基づいてグループを残します。とにかく、視覚的にフォーマットされた文字列が続きます。また、Order By も期日に基づいているため (きれいにフォーマットされた文字列バージョンではありません)、問題ありません。

クエリ自体の日付範囲については...指定された範囲内にいくつのレコードがあるか。

リビジョン

クエリで使用される要素のマルチパート インデックスを利用できる場合があるため、クエリは実際にページ データに移動して、レコード全体から個々の要素を確認する必要はありません。データはインデックス キーの一部になるため、クエリはそれを直接使用でき、ページに移動する必要はありません。

インデックスを試してみる

INDEX on ... ( DueDate, status, IsAward, TypeOfNotice, ValidIndicator )

また、クエリの alias.fields を明確にするために。「a」を明示的に参照することがあります。エイリアスとそれ以外の場合、エイリアスはありません。あなたの後にクエリに取り組んでいる他の人、または助けを提供しようとしている他の人のために。適切なエイリアスを使用してすべてのフィールドを明示的に参照することが容易になり、どのテーブルのどの列のあいまいさを防ぐことができます。はい、ここでテーブル構造を提供しましたが、将来は構造を振り返るよりも簡単になる可能性があります。

于 2012-05-14T11:06:23.103 に答える
0

まあ、それ

FROM tblNotices AS a LEFT JOIN tblTransactions AS b 
ON a.id = b.noticeid WHERE b.noticeid IS NOT NULL

と同じです

FROM tblNotices AS a INNER JOIN tblTransactions AS b 
ON a.id = b.noticeid

2 番目の方が速い可能性があります。

期日ごとにグループ化してみませんか? 次に、DATE_FORMAT() を省略できますが、それは単なるピーナッツだと思います。これを省略すると、ORDER BYGROUP BY に関係するため、これも必要ありません。

それ以外にできることはあまりありません。

于 2012-05-14T11:06:07.890 に答える