多くの人は、「OR」条件で2つのインデックス付きカラムにインデックスを使用しないというMySQLの問題を知っています。 より詳細には、テーブルにインデックスが付加された複数の列があり、「OR」条件を使用してこれらの列のサンプルが作成されます。 インデックスは機能しません。 現時点でPostgreSQLについて少し知りたいという目標を設定したため、PostgreSQLと比較してこの点を調査することにしました。
説明のために、2つの異なるデータベースに対して次のSQLクエリを実行します。 まず、MySQLで「OR」条件を使用して状況を繰り返しましょう。
1.テストパターンを作成します。
MariaDB [metemplate]> create table example (a int, b int);
2.いくつかの値を挿入します。
MariaDB [metemplate]> select * from example; +
3. 2つの列にインデックスを作成します。
MariaDB [metemplate]> create index a_idx on example(a); MariaDB [metemplate]> create index b_idx on example(b);
4.「OR」条件を介して2列のサンプリングでクエリを作成します。
MariaDB [metemplate]> explain select * from example where a=1 or b=1\G; *************************** 1. row *************************** id: 1 select_type: SIMPLE table: example type: ALL possible_keys: a_idx,b_idx key: NULL key_len: NULL ref: NULL rows: 8 Extra: Using where 1 row in set (0.00 sec)
この場合、MySQLデータベースはフェッチ時に2つのインデックスのどちらも使用しないことが明確にわかります。 この状況での標準的な解決策は、ユニオンを使用して、作成されたインデックスの使用をキャプチャすることです。
MariaDB [metemplate]> explain select * from example where a=1 union select * from example where b=1\G; *************************** 1. row *************************** id: 1 select_type: PRIMARY table: example type: ref possible_keys: a_idx key: a_idx key_len: 5 ref: const rows: 2 Extra: *************************** 2. row *************************** id: 2 select_type: UNION table: example type: ref possible_keys: b_idx key: b_idx key_len: 5 ref: const rows: 1 Extra: *************************** 3. row *************************** id: NULL select_type: UNION RESULT table: <union1,2> type: ALL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: NULL Extra: 3 rows in set (0.00 sec)
5. PostgeSQLデータベースのデータを使用して同様のテーブルを作成し、「OR」条件で同様のケースを作成しようとします。
metemplate=
インデックスは機能しません。以前に使用されたユニオンアプローチを試してください。
metemplate=
インデックスは使用されません。
MySQLが疑っていたよりもPostgeSQLがインデックスでより効率的に動作することを聞いた
どうやらPostgeSQLのテーブルにはほとんどデータがないため、より多くのデータが生成されます。
metemplate=
このようなボリュームでは、インデックスが使用され、実際にPostgreSQLは「OR」条件で動作できます。
metemplate=