2011-07-26 16 views
1

アイテムの特定の関係に基づいて、可変数の列を含む非常に特定のレポートのクエリを作成しています。必要に応じてクエリを変更する方法についてsuggetionsが公開されていますが、それは可能だとは思いません。私はこれをループで実行するのではなく、単一のクエリとして保持することをお勧めします。検索対象の表には約400万レコードが含まれており、アーカイブすることはできません。MySQL複数の日付サブクエリ

私が知りたいのは、DATEADDインデックスが同じテーブルにある外部クエリで使用されているにもかかわらず、サブクエリで使用されていない理由です。私は、フィールド上の関数がMySQLのインデックス作成を停止することを認識していますが、これはアイテムにのみあり、あなたが比較しているものではありません。

レポートの結果は、何かが発生した範囲内の各日付の各特定の項目(サブクエリ)の番号です。日付範囲は動的に生成されます。サブクエリは1日の結果を返す必要があります

私たちはバージョン5.0.77を使用していますが、これは当社のホスティングプロバイダによって管理されているため変更できません。ここで

はクエリです:

SELECT DATE_FORMAT(DATEADD, '%d/%m/%y') AS DATEADD, 

    (SELECT COUNT(ID) 
     FROM ATABLE AS 
    WHERE ELEMNAME = 'ANELEMENT' AND COMPID = 132 
      AND VT.DATEADD BETWEEN CONCAT(DATE(V.DATEADD)," 00:00:00") AND CONCAT(DATE(V.DATEADD)," 23:59:59"))) 
     AS '132', 

    (SELECT COUNT(ID) 
     FROM ATABLE AS 
    WHERE ELEMNAME = 'ANELEMENT' AND COMPID = 149 
      AND VT.DATEADD BETWEEN CONCAT(DATE(V.DATEADD)," 00:00:00") AND CONCAT(DATE(V.DATEADD)," 23:59:59"))) 
     AS '149' 

FROM ATABLE AS V 
WHERE 1 = 1 AND COMPID = 132 
    AND (V.DATEADD >= "2010-09-01 00:00:00" 
     AND V.DATEADD <= "2010-10-26 23:59:59") 
    AND 1 = 1 
    AND ELEMNAME = 'ANELEMENT' 
GROUP BY DATE_FORMAT(DATEADD, '%Y-%m-%d') 

回数サブクエリが実行され、このアイテムが持つリンク数に依存し、クエリが構築されているときに決定されます。我々は試してみました

: のいずれかが、このdoesntの仕事

"VT.DATEADD <= DATE(V.DATEADD) and VT.DATEADD <= DATE(V.DATEADD) +1" 

との間の交換、

"VT.DATEADD = DATE(V.DATEADD)" 

にそれを変更すると、インデックスを使用しないが、しかし、行の正しい数を返すdoesntの、 DATEADDは日時であるためです。我々はそれを変更した場合:

"VT.DATEADD >= "2010-09-01" AND VT.DATEADD <= "2010-09-02" 

説明からの出力は、(使用され使用可能ですが、ない場合)USE INDEX、またはFORCE INDEXを使用して

+----+--------------------+-------+-------+-------------------------+----------+---------+-------+-------+----------------------------------------------+ 
| id | select_type  | table | type | possible_keys   | key  | key_len | ref | rows | Extra          | 
+----+--------------------+-------+-------+-------------------------+----------+---------+-------+-------+----------------------------------------------+ 
| 1 | PRIMARY   | V  | range | DATEADD,COMPID,ELEMNAME | DATEADD | 8  | NULL | 1386 | Using where; Using temporary; Using filesort | 
| 2 | DEPENDENT SUBQUERY | VT | ref | COMPID,ELEMNAME   | ELEMNAME | 103  | const | 44277 | Using where         | 
+----+--------------------+-------+-------+-------------------------+----------+---------+-------+-------+----------------------------------------------+ 

で固定せずにNULLキー

を使用していますこれは、クエリは非常にゆっくりと実行され、わずかな期間にわたって実行され、データベースがロックされます。

答えて

0

私はあなたが全体的にしたいものを単純化しすぎているかどうかわかりませんが、これはあなたのために働くでしょう。特定の日付範囲内の2つの「compid」値のアクティビティの量を知りたいと思うようです。

SELECT 
     DATE_FORMAT(DATEADD, '%Y-%m-%d'), 
     SUM(if(compid = 132, 1, 0)) as Count132, 
     SUM(if(compid = 149, 1, 0)) as Count149 
    from 
     ATable 
    where 
      elemname = "ANELEMENT" 
     AND (compid = 132 or compid = 149) 
     AND DATEADD BETWEEN "2010-09-01 00:00:00" AND "2010-10-26 23:59:59" 
    group by 
     dateadd 
+0

全く簡略化されていません。実際、それは上にあった!おかげさまで、私と他のプログラマーは、今日の朝、何時間か作業していました。何らかの理由で私たちの心がサブクエリモードに陥っていました。私たちはどちらも "DOH !!"の行に沿って何かを言った –

+0

@Zack Newsham、Doooohhhhhと一緒に何度も頭を打った!! – DRapp

+0

申し訳ありませんが、迅速なフォローアップ、私は別の記事で私は "あなたの評判を与える"などを見たが、どうすればよいですか、私はちょうどそれが自動的に起こるあなたの答えを受け入れる必要がありますか? –