2015-11-05 45 views
2
TableA 
------ 
id 
Name 
other_fields 

TableB 
------ 
A_id (foreign key to TableA.id) 
other_fields 

选择条目从TableB TableA中所参考条目与一些特定的属性(如Name = "Alice"一个在这里加入似乎没有必要

这可以通过加入很容易做到:

SELECT TableB.* 
FROM TableA INNER JOIN TableB on TableA.id = TableB.A_id 
WHERE TableA.Name = "Alice" 

被用于程序编程,加入似乎矫枉过正并且没有必要,因为我们实际上并不需要来自TableA的任何信息,而不是idAlice

所以 - 假设Alice是独一无二的 - 有没有办法做到这一点(伪):

variable alice_id = get id of Alice from TableA 

SELECT * 
FROM TableB 
WHERE A_id = alice_id 

如果是的话,是否应该有利于传统连接方法的使用呢?速度更快吗? (原则上,当然)

+0

相关:http://stackoverflow.com/questions/5274618/inner-join-and-where-in-clause-performance –

回答

3

你问,如果你能做到这一点:

SELECT * FROM TableB WHERE A_id = (SELECT id FROM TableA WHERE Name = 'Alice'); 

这是一个完全合法的查询,但MySQL将执行好得多做加盟,因为子查询的处理第二个单独查询。使用MySQL EXPLAIN命令(只要将它放在SELECT查询的前面)将显示用于查询的索引,临时表和其他资源。当一个查询比另一个查询更快或更有效时,它应该给你一个想法。

+0

被用于C++,对我来说JOINS似乎是最糟糕的罪恶。我在思想上将它们与创建2个矩阵的新矩阵联系起来。需要围绕sql的方式来处理我的头。 – bolov

+0

SQL是一个不同的范例。关系数据库经过优化以处理连接。使用程序代码避免连接几乎是一种反模式。 – APC

+0

换句话说...... C++只能与标量一起工作; SQL优化用于处理矢量。一致做事,不要迭代。 –

1

对于您的工作负载和索引,您应该尝试查询的执行计划和运行时。无论哪种情况,您都可以从名称索引中受益。

我相信这两个查询都会以类似的计划结束。我们来检查一下。

创建表

create table tablea (id int primary key, nm as varchar(50)); 
create index idx_tablea_nm on tablea(nm); 
create table tableb(a_id int, anotherfield varchar(100), 
     key idx_tableb_id(a_id), 
     constraint fk_tableb_tablea_id foreign key (a_id) references tablea (id)); 

让我们在第一个做一个EXPLAIN

explain select tableb.* from tablea inner join tableb on tablea.id = tableb.a_id where tablea.nm = 'Alice'; 
+----+-------------+--------+------+-----------------------+---------------+---------+-------------------+------+--------------------------+ 
| id | select_type | table | type | possible_keys   | key   | key_len | ref    | rows | Extra     | 
+----+-------------+--------+------+-----------------------+---------------+---------+-------------------+------+--------------------------+ 
| 1 | SIMPLE  | tablea | ref | PRIMARY,idx_tablea_nm | idx_tablea_nm | 53  | const    | 1 | Using where; Using index | 
| 1 | SIMPLE  | tableb | ref | idx_tableb_id   | idx_tableb_id | 5  | tablea.id   | 1 | Using where    | 
+----+-------------+--------+------+-----------------------+---------------+---------+-------------------+------+--------------------------+ 

让我们做EXPLAIN上第二个:

explain select * from tableb where a_id = (select id from tablea where nm = 'Alice'); 
+----+-------------+--------+------+---------------+---------------+---------+-------+------+--------------------------+ 
| id | select_type | table | type | possible_keys | key   | key_len | ref | rows | Extra     | 
+----+-------------+--------+------+---------------+---------------+---------+-------+------+--------------------------+ 
| 1 | PRIMARY  | tableb | ref | idx_tableb_id | idx_tableb_id | 5  | const | 1 | Using where    | 
| 2 | SUBQUERY | tablea | ref | idx_tablea_nm | idx_tablea_nm | 53  |  | 1 | Using where; Using index | 
+----+-------------+--------+------+---------------+---------------+---------+-------+------+--------------------------+ 

我没有这些表格中的数据很多,只有很少的数据,您会注意到相同的性能。随着工作量的变化,执行玩可能会更改