6
sqlite> explain query plan select max(utc_time) from RequestLog;
0|0|0|SEARCH TABLE RequestLog USING COVERING INDEX key (~1 rows) # very fast

sqlite> explain query plan select min(utc_time) from RequestLog;
0|0|0|SEARCH TABLE RequestLog USING COVERING INDEX key (~1 rows) # very fast

sqlite> explain query plan select min(utc_time), max(utc_time) from RequestLog;
0|0|0|SCAN TABLE RequestLog (~8768261 rows) # will be very very slow

minと を別々に使用していますmaxが、完全に機能します。ただし、何らかの理由でminand を一緒に選択している間、sqlite はインデックスを「忘れて」しまいます。max私ができる設定はありますか (私はAnalyzeすでに使用しましたが、動作しません)? または、この動作の説明はありますか?

編集1

sqlite> .schema 

CREATE TABLE FixLog(
                    app_id text,  __key__id INTEGER,
                    secret text, trace_code text, url text,
                    action text,facebook_id text,ip text,
                    tw_time datetime,time datetime,
                    tag text,to_url text,
                    from_url text,referer text,weight integer,
                    Unique(app_id, __key__id)
                    );
CREATE INDEX key4 on FixLog(action);
CREATE INDEX time on FixLog(time desc);
CREATE INDEX tw_time on FixLog(tw_time desc);



sqlite> explain query select min(time) from FixLog;
0|0|0|SEARCH TABLE FixLog USING COVERING INDEX time (~1 rows)
sqlite> explain query select max(time) from FixLog;
0|0|0|SEARCH TABLE FixLog USING COVERING INDEX time (~1 rows)
sqlite> explain query plan select max(time), min(time) from FixLog;
0|0|0|SCAN TABLE FixLog (~1000000 rows)
4

1 に答える 1

7

http://www.sqlite.org/optoverview.html#minmaxで説明されているように、これは sqlite クエリ オプティマイザーの既知の癖です。

次の形式のクエリは、適切なインデックスが存在すると仮定して、対数時間で実行するように最適化されます。

 SELECT MIN(x) FROM table;
 SELECT MAX(x) FROM table;

これらの最適化を行うには、テーブルと列の名前のみを変更して、上記の形式で正確に表示する必要があります。WHERE 句を追加したり、結果に対して演算を行ったりすることは許可されていません。結果セットには 1 つの列が含まれている必要があります。MIN 関数または MAX 関数の列は、インデックス付きの列である必要があります。

更新 (2017/06/23): 最近、これは更新され、単一の MAX または MIN を含むクエリは、インデックス ルックアップ (算術などを可能にする) によって満たされる可能性があることが示されました。ただし、1 つのクエリでそのような集計演算子を複数使用することはできません (そのため、MIN,MAX は依然として遅くなります)。

引数がインデックスの一番左の列である単一の MIN() または MAX() 集計関数を含むクエリは、テーブル全体をスキャンするのではなく、単一のインデックス ルックアップを実行することによって満たされる場合があります。例:

SELECT MIN(x) FROM table;
SELECT MAX(x)+1 FROM table;
于 2012-08-25T06:12:35.653 に答える