sql >> データベース >  >> RDS >> Mysql

MySQL/PostgreSQLのINキーワードの速度

    PostgreSQLでは、ここで取得する内容は基になるテーブルによって異なるため、データの有用なサブセットに対していくつかのサンプルクエリでEXPLAIN ANALYZEを使用して、オプティマイザが何を実行するかを正確に把握する必要があります(テーブルがに対して実行されていることも分析されています)。 INはいくつかの異なる方法で処理できるため、データに使用されている代替案を特定するためにいくつかのサンプルを調べる必要があります。あなたの質問に対する簡単な一般的な答えはありません。

    リビジョンで追加した特定の質問については、インデックスが含まれていない些細なデータセットに対して、次の2つのクエリプランの例を示します。

    postgres=# explain analyze select * from x where s in ('123','456');
     Seq Scan on x  (cost=0.00..84994.69 rows=263271 width=181) (actual time=0.015..1819.702 rows=247823 loops=1)
       Filter: (s = ANY ('{123,456}'::bpchar[]))
     Total runtime: 1931.370 ms
    
    postgres=# explain analyze select * from x where s='123' or s='456';
     Seq Scan on x  (cost=0.00..90163.62 rows=263271 width=181) (actual time=0.014..1835.944 rows=247823 loops=1)
       Filter: ((s = '123'::bpchar) OR (s = '456'::bpchar))
     Total runtime: 1949.478 ms
    

    実際の処理時間はテーブル全体の順次スキャンによって支配されるため、これら2つのランタイムは基本的に同じです。複数回実行すると、2つの違いが実行から実行までの許容誤差を下回っていることを示します。ご覧のとおり、PostgreSQLはINケースをANYフィルターを使用するように変換します。これは、一連のORよりも常に高速に実行されるはずです。繰り返しになりますが、この些細なケースは、インデックスなどが関係する深刻なクエリで表示される内容を必ずしも表すものではありません。とにかく、INを一連のORステートメントに手動で置き換えることは、決して速くなることはありません。オプティマイザーは、処理するのに適したデータがある場合、ここで行う最善のことを知っているからです。

    一般に、PostgreSQLは、MySQLオプティマイザーよりも複雑なクエリを最適化する方法について多くのトリックを知っていますが、オプティマイザーに処理するのに十分なデータを提供したことに大きく依存しています。 PostgreSQL wikiの「パフォーマンスの最適化」セクションの最初のリンクは、オプティマイザーから良好な結果を得るのに必要な最も重要なことをカバーしています。



    1. MySQLCAPIおよびC++を使用したMySQLデータベーステーブルの行のフェッチ

    2. 基本的なMySQLクエリ

    3. タイムスタンプに対する開始時刻と終了時刻の間のPostgreSQLマッチング間隔

    4. 名前パターンに一致するMySQLデータベース内のすべてのテーブルを切り捨てます