Jam*_*vec 35 mysql sql indexing performance
我知道索引的重要性以及连接顺序如何改变性能.我已经完成了一堆与多列索引相关的阅读,但没有找到我的问题的答案.
我很好奇我是否做了多列索引,如果他们指定的顺序很重要.我的猜测是它不会,并且引擎会将它们视为一个组,其中排序无关紧要.但我想验证一下.
例如,来自mysql的网站(http://dev.mysql.com/doc/refman/5.0/en/multiple-column-indexes.html)
CREATE TABLE test (
id INT NOT NULL,
last_name CHAR(30) NOT NULL,
first_name CHAR(30) NOT NULL,
PRIMARY KEY (id),
INDEX name (last_name,first_name)
);
Run Code Online (Sandbox Code Playgroud)
在任何情况下,如果以下情况会更好,或者它是否相同,会不会有任何好处?
CREATE TABLE test (
id INT NOT NULL,
last_name CHAR(30) NOT NULL,
first_name CHAR(30) NOT NULL,
PRIMARY KEY (id),
INDEX name (first_name,last_name)
);
Run Code Online (Sandbox Code Playgroud)
Specificially:
INDEX name (last_name,first_name)
Run Code Online (Sandbox Code Playgroud)
VS
INDEX name (first_name,last_name)
Run Code Online (Sandbox Code Playgroud)
Bil*_*win 65
在讨论多列索引时,我使用类比电话簿.电话簿基本上是姓氏的索引,然后是名字.因此排序顺序取决于哪个"列"是第一个.搜索分为几类:
如果您查找姓氏为Smith的人,您可以轻松找到它们,因为该书按姓氏排序.
如果你查找姓名为约翰的人,那么电话簿就无济于事,因为约翰斯分散在整本书中.你必须扫描整本电话簿才能找到它们.
如果您查找具有特定姓氏Smith和特定名字John的人,该书有帮助,因为您发现Smiths排序在一起,并且在该组Smiths中,Johns也按排序顺序找到.
如果你有一个按姓氏和姓氏排序的电话簿,那么书的分类将有助于你进入上述案例#2和#3,但不是案例#1.
这解释了查找确切值的情况,但如果您按值范围查找会怎么样?假设你想找到所有姓名为John且姓氏以'S'开头的人(Smith,Saunders,Staunton,Sherman等).约翰斯在每个姓氏中的"J"下排序,但是如果你想要所有姓氏的所有姓氏以"S"开头,那么约翰斯就不会归为一类.它们再次分散,因此您最终必须扫描姓氏以"S"开头的所有姓名.如果电话簿是按名字和姓氏组织的,那么你会发现所有的约翰斯在一起,然后在约翰内,所有'S'姓都将被组合在一起.
因此,多列索引中列的顺序绝对重要.一种类型的查询可能需要索引的特定列顺序.如果您有多种类型的查询,则可能需要多个索引来帮助它们,并且列具有不同的顺序.
您可以阅读我的演示文稿如何设计索引,真的可以获得更多信息.
Gor*_*off 12
这两个指标是不同的.这在MySQL和其他数据库中都是如此.MySQL在解释文档中的不同方面做得非常好.
考虑两个索引:
create index idx_lf on name(last_name, first_name);
create index idx_fl on name(first_name, last_name);
Run Code Online (Sandbox Code Playgroud)
这两个应该同样适用于:
where last_name = XXX and first_name = YYY
Run Code Online (Sandbox Code Playgroud)
idx_lf将是以下条件的最佳选择:
where last_name = XXX
where last_name like 'X%'
where last_name = XXX and first_name like 'Y%'
where last_name = XXX order by first_name
Run Code Online (Sandbox Code Playgroud)
idx_fl将是以下的最佳选择:
where first_name = YYY
where first_name like 'Y%'
where first_name = YYY and last_name like 'X%'
where first_name = XXX order by last_name
Run Code Online (Sandbox Code Playgroud)
对于其中许多情况,可能会使用这两个索引,但其中一个是最佳的.例如,考虑使用查询的idx_lf:
where first_name = XXX order by last_name
Run Code Online (Sandbox Code Playgroud)
MySQL可以使用idx_lf读取整个表,然后在之后进行过滤order by.我不认为这是实践中的优化选项(对于MySQL),但这可能发生在其他数据库中.
一般规则是,你想要把最具选择性的 - 也就是那个能给你最少的结果 - 首先.因此,如果您在一个表上创建一个多列索引,其中包含status10个可能值的dateAdded列,以及一个列,您通常会编写类似的查询
SELECT * FROM myTable WHERE status='active' and dateAdded='2010-10-01'
Run Code Online (Sandbox Code Playgroud)
...那么你dateAdded首先需要,因为这会将扫描限制在几行而不是行的10%(或者"活动"的任何比例).
这需要相当多的思考和调整; 你应该看看Lahdenmaki和Leach的书.