我正在使用Mysql 5.0,对索引有点新意。通过索引可以帮助下列哪些查询以及我应该创建哪个索引?
(不要假设任何一个表都有唯一的值。这不是功课,它只是我编写的一些例子,试图让我的头脑进行索引。)
Query1:
Select a.*, b.*
From a
Left Join b on b.type=a.type;
Query2:
Select a.*, b.*
From a,b
Where a.type=b.type;
Query3:
Select a.*
From a
Where a.type in (Select b.type from b where b.brand=5);
以下是我猜测哪些索引将用于这些不同类型的查询:
Query1:
Create Index Query1 Using Hash on b (type);
Query2:
Create Index Query2a Using Hash on a (type);
Create Index Query2b Using Hash on b (type);
Query3:
Create Index Query2a Using Hash on b (brand,type);
我是否认为Query1或Query3都不会使用表a上的任何索引?
我相信这些都应该是哈希,因为只有=或!=,对吧?
由于
答案 0 :(得分:1)
查询3无效,但我认为你的意思是
where a.type in ....
查询1与查询2相同,只是更好的语法,两者可能具有相同的查询计划,并且两者都将使用这两个索引。
查询3将使用b.brand上的索引,但不使用它的类型部分。如果你有一个索引,它也会在a.type上使用索引。
他们应该是哈希索引。
答案 1 :(得分:1)
在mysql中使用explain命令将提供很多有关mysql正在做什么以及如何优化查询的信息。
q1和q2中的:(a.type,所有其他cols)和一个on(b.type,所有其他b cols)的索引 在q3中:(a.b_type,所有其他cols)和b上的一个索引(品牌,类型)
理想情况下,您希望所选的所有列都直接存储在索引中,以便mysql不必从索引跳回到表数据以获取所选列。然而,这并不总是可以管理的(即:有时你需要选择*并将所有列索引成本太高),在这种情况下,仅索引搜索列就可以了。
所以你说的一切都很棒。
答案 2 :(得分:1)
如果品牌= 5的b的数量接近于零,则查询3可以利用a.type上的索引
如果它们是B树(并因此被排序),则Query2将使用索引。使用带索引连接的哈希索引可能会降低查询速度(因为您必须以非顺序方式读取大小(a)值)
答案 3 :(得分:1)
查询优化和索引是一个很大的主题,因此您肯定希望阅读有关MySQL和您正在使用的特定存储引擎的信息。 InnoDB和NDB支持“使用哈希”;我不认为MyISAM支持它。
即使连接条件相等,您所拥有的连接也将执行完整的表或索引扫描;必须读取每一行,因为没有where子句。
使用标准b-tree索引可能会更好,但要测量它并使用“explain”调查查询计划。 MySQL InnoDB存储按主键组织的行数据,因此您还应该在表上使用主键,而不仅仅是索引。最好是在连接中使用主键,否则MySQL会从索引中检索主键,然后再执行另一次获取以获取行。该规则的一个很好的例外是,如果您的二级索引包含查询中所需的所有列。这被称为覆盖索引,MySQL根本不必查找该行。