2

SQLクエリを最適化しようとしています。問題はそれが非常に遅いということです!私はsqliteと中規模のデータセット(20000row)で作業しています。私のSQL構文は次のようになります。

SELECT DISTINCT date(A.last_update) as lastUpdate,
(SELECT COUNT(*) FROM bgp_update AS B WHERE date(B.last_update) = date(A.last_update) AND B.validity = 1) AS valid,
(SELECT COUNT(*) FROM bgp_update AS B WHERE date(B.last_update) = date(A.last_update) AND B.validity = 0) AS invalid,
(SELECT COUNT(*) FROM bgp_update AS B WHERE date(B.last_update) = date(A.last_update) AND B.validity = -1) AS notFound
FROM (SELECT DISTINCT last_update FROM bgp_update ORDER BY last_update) AS A WHERE last_update BETWEEN '%var' and '%var2';

以下は私が持っているものの例です:

id   |     last_update   |  Validity

48   | 2009-1-6 18:34:38 |  notFound   
47   | 2009-1-6 18:34:38 |  valid   
46   | 2009-1-6 18:34:38 |  valid    
45   | 2009-1-3 18:34:38 |  invalid   
44   | 2009-1-3 18:34:38 |  invalid   
42   | 2009-1-4 18:34:38 |  notFound 
41   | 2009-1-4 18:34:38 |  notFound
48   | 2009-1-4 18:34:38 |  valid

そして、クエリ結果は次のようになります。

    Date   |  valid   |  invalid   |    notFound

  2009-1-3 |   0      |     2      |       0
  2009-1-4 |   1      |     0      |       2
  2009-1-6 |   2      |     0      |       1

それから線グラフを生成するためにこれが必要です。例は次のようになります。折れ線グラフ

しかし、私が言ったように、クエリは非常に遅いです!どうすれば速くできますか?

::::2.編集:::::

前の説明では、問題を単純化しました。私のテーブル作成ステートメントは次のようになります。

CREATE TABLE bgp_update
    (id INTEGER PRIMARY KEY,
    ip VARCHAR(64) NOT NULL,
    mask INTEGER NOT NULL,
    asn INTEGER NOT NULL,
    validity INTEGER NOT NULL,
    last_update TIMESTAMP DEFAULT CURRENT_TIMESTAMP)

ご覧のとおり、私のクエリではlast_updateフィールドとvalidityフィールドのみを使用しています。

4

3 に答える 3

3

日付値が関数によって理解される適切な形式であると仮定すると、dateチェックする条件を単純に合計できます(ブール式は0または1を返すだけなので)。

SELECT date(last_update) AS Date,
       sum(validity = 'valid'   ) AS valid,
       sum(validity = 'invalid' ) AS invalid,
       sum(validity = 'notFound') AS notFound
FROM bgp_update
WHERE last_update BETWEEN ? AND ?
GROUP BY date(last_update)
ORDER BY date(last_update)

このクエリは、列にインデックスがある場合は効率的ですが、列と列にカバーするインデックスlast_updateがある場合はもう少し効率的です。last_updatevalidity

于 2013-01-27T11:53:55.330 に答える
2

ケースステートメントで合計を使用できます。例:

select last_update,
  sum(case when validity=1 then 1 else 0 end) valid,
  sum(case when validity=0 then 1 else 0 end) invalid,
  sum(case when validity=-1 then 1 else 0 end) notfound
from bgp_update
where last_update between '1/1/2013' and '1/2/2013'
group by last_update
order by last_update

SQLフィドル

于 2013-01-27T03:05:55.273 に答える
0

ネストされたサブクエリは、クエリを非常に非効率的にすることがあります。結合を使用するようにクエリを書き直すことを検討してください。

次に、レコードが最も少ないテーブルがクエリの先頭に最も近い場所で、結合された要素を再配置できます。そうすることで、MySQLが他のテーブルから行を取得するためにソートする必要のあるレコードの数を減らすことができます。

さらに、調べている特定の値を持つID列およびテーブルの列にインデックスを使用することを検討することをお勧めします。

他のすべてが失敗した場合、3つの別々のクエリが最も効率的であることがわかるかもしれません。

于 2013-01-27T02:48:44.330 に答える