WHERE条件にuser_id=Xまたはuser_idIN(結果を返さない可能性のあるサブクエリ)のチェックが含まれるクエリを最適化するにはどうすればよいですか?
以下の私の例では、クエリ1と2はどちらも非常に高速(<1 ms)ですが、クエリ3はクエリ1と2の条件の単なるORであり、はるかに低速です(50 ms)
誰かがクエリ3が非常に遅い理由を説明できますか?また、一般に、この問題を回避するためにどのタイプのクエリ最適化戦略を追求する必要がありますか?私の例のサブクエリは簡単に削除できることを理解していますが、実際には、サブクエリが必要なデータを取得するための最も簡単な方法のように見えることがあります。
関連するコードとデータ:
投稿データ https://dl.dropbox.com/u/4597000/StackOverflow/sanitized_posts.csv
ユーザーデータ https://dl.dropbox.com/u/4597000/StackOverflow/sanitized_users.csv
# from the shell:
# > createdb test
CREATE TABLE posts (
id integer PRIMARY KEY NOT NULL,
created_by_id integer NOT NULL,
created_at integer NOT NULL
);
CREATE INDEX index_posts ON posts (created_by_id, created_at);
CREATE INDEX index_posts_2 ON posts (created_at);
CREATE TABLE users (
id integer PRIMARY KEY NOT NULL,
login varchar(50) NOT NULL
);
CREATE INDEX index_users ON users (login);
COPY posts FROM '/path/to/sanitized_posts.csv' DELIMITERS ',' CSV;
COPY users FROM '/path/to/sanitized_users.csv' DELIMITERS ',' CSV;
-- queries:
-- query 1, fast:
EXPLAIN ANALYZE SELECT * FROM posts WHERE created_by_id = 123 LIMIT 100;
-- query 2, fast:
EXPLAIN ANALYZE SELECT * FROM posts WHERE created_by_id IN (SELECT id FROM users WHERE login = 'nobodyhasthislogin') LIMIT 100;
-- query 3, slow:
EXPLAIN ANALYZE SELECT * FROM posts WHERE created_by_id = 123 OR created_by_id IN (SELECT id FROM users WHERE login = 'nobodyhasthislogin') LIMIT 100;