出于好奇,有人知道你做的时候是否有任何重大的性能差异......
Select something Where foo=1
......和......
Select something Where foo In(1) #just one item not multiple
...单个或联合SQL查询中的Mysql和Postgresql。
问题是我正在构建Ruby on Rails scopes,我想知道哪种方法更好,
为多个项目(IN)创建一个范围,为使用相等(=)
的单个项目创建一个范围scope :with_owner_ids, lambda{|owner_class, *ids| where(owner_type: owner_class.model_name, owner_id: ids.flatten)}
scope :with_owner, lambda{|owner| where(owner_type: owner.class.model_name, owner_id: owner.id)}
#... where `foos`.`owner_class`='User' and `foos`.`owner_id` = 15
或更清洁,为多个项目(IN)创建范围,而不是将此范围传递给单个项目的另一个范围(IN也是如此)
scope :with_owner_ids, lambda{|owner_class, *ids| where(owner_type: owner_class.model_name, owner_id: ids.flatten)}
scope :with_owner, lambda{|owner| with_owner_ids(owner.class, owner.id)}
#... where `foos`.`owner_class`='User' and `foos`.`owner_id` IN (15)
答案 0 :(得分:4)
一个非常简单的表上的PostgreSQL示例:
CREATE TABLE a (
a_id integer
, t_id integer
);
COPY a
FROM STDIN;
1 1
2 1
3 1
4 4
\.
EXPLAIN ANALYZE SELECT * FROM a WHERE t_id IN (1);
Seq Scan on a (cost=0.00..36.75 rows=11 width=8) (actual time=0.056..0.059 rows=3 loops=1)
Filter: (t_id = 1)
Total runtime: 41.795 ms
从Filter: (t_id = 1)
部分可以清楚地看出IN (1)
被翻译成一个简单的等式检查,因此这两种形式没有区别。
我将MySQL部分留给其他人:)
答案 1 :(得分:0)
我玩过MySQL EXPLAIN:
<强>等于强>
mysql> explain extended select * from document_name_ownerships as dno join document_names as dn on dn.id = dno.document_name_id where dn.id = 18 ;
+----+-------------+-------+-------+---------------+---------+---------+-------+------+----------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+-------+---------------+---------+---------+-------+------+----------+-------------+
| 1 | SIMPLE | dn | const | PRIMARY | PRIMARY | 4 | const | 1 | 100.00 | |
| 1 | SIMPLE | dno | ALL | NULL | NULL | NULL | NULL | 81 | 100.00 | Using where |
+----+-------------+-------+-------+---------------+---------+---------+-------+------+----------+-------------+
2
rows in set, 1 warning (0.00 sec)
<强>在()强>
mysql> explain extended select * from document_name_ownerships as dno join document_names as dn on dn.id = dno.document_name_id where dn.id in(18) ;
+----+-------------+-------+-------+---------------+---------+---------+-------+------+----------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+-------+---------------+---------+---------+-------+------+----------+-------------+
| 1 | SIMPLE | dn | const | PRIMARY | PRIMARY | 4 | const | 1 | 100.00 | |
| 1 | SIMPLE | dno | ALL | NULL | NULL | NULL | NULL | 81 | 100.00 | Using where |
+----+-------------+-------+-------+---------------+---------+---------+-------+------+----------+-------------+
2 rows in set, 1 warning (0.01 sec)
因此,当涉及到一条记录时,等于(=)似乎比 IN()快得多
但有趣的是,当我完成几个项目时,结果是相同的:
mysql> explain extended select * from document_name_ownerships as dno join document_names as dn on dn.id = dno.document_name_id where dn.id = 18 or dn.id=17 or dn.id=19;
> (0.00 sec)
mysql> explain extended select * from document_name_ownerships as dno join document_names as dn on dn.id = dno.document_name_id where dn.id in (18, 17, 19);
> (0.00 sec)
但不知道这个结果是否可以在实时服务器上受到信任,因为在我的开发机器上我有SSD驱动器......但对我来说似乎是一样的
<强>更新强>
有70000条记录
select * from document_name_ownerships as dno join document_names as dn on dn.id = dno.document_name_id where dn.id = 60811;
1 row in set (0.04 sec)
select * from document_name_ownerships as dno join document_names as dn on dn.id = dno.document_name_id where dn.id in( 60811);
1 row in set (0.04 sec)
多个
select * from document_name_ownerships as dno join document_names as dn on dn.id = dno.document_name_id where dn.id in( 60800, 11111, 22222, 40000);
4 rows in set (0.07 sec)
select * from document_name_ownerships as dno join document_names as dn on dn.id = dno.document_name_id where dn.id = 60800 or dn.id = 11111 or dn.id = 22222 or dn.id = 40000;
4 rows in set (0.08 sec)