简体   繁体   English

解释查询-MySQL不使用表索引

[英]Explain query - MySQL not using index from table

I'm trying to learn the explain statement in MySQL but ran into a wall. 我正在尝试学习MySQL中的explain语句,但遇到了麻烦。

For my experiment, I created two tables (each having 10 rows) and ran explain over a simple join. 对于我的实验,我创建了两个表(每个表有10行),并通过一个简单的联接进行了explain Naturally, no indexes were used and 10*10 = 100 rows were scanned (I've added the output in images because the very long output of EXPLAIN was being wrapped on itself. The code is also in this pastebin ): 自然,不使用任何索引,而是扫描10 * 10 = 100行(我在图像中添加了输出,因为EXPLAIN的非常长的输出被自身包装了。代码也位于此pastebin中 ):

坏表设计

I then added primary keys and indexes and reissued the explain command: 然后,我添加了主键和索引,并重新发出了explain命令:

在此处输入图片说明

But as you can see, the users table is still being fully scanned by MySQL, as if there was no primary key. 但是如您所见,MySQL仍在完全扫描用户表,就好像没有主键一样。 What is going wrong? 怎么了?

This is a bit long for a comment. 这有一段评论的时间。

Basically, your tables are too small. 基本上,您的桌子太小了。 You cannot get reasonable performance indications on such small data -- the query only needs to load two data pages into memory for the query. 对于如此小的数据,您无法获得合理的性能指示-查询仅需要将两个数据页加载到内存中以进行查询。 A nested loop join requires 100 comparisons. 嵌套循环联接需要100次比较。 By comparison, loading indexes and doing the binary search is probably about the same amount of effort, if not more. 相比之下,加载索引和执行二进制搜索的工作量大约相同,甚至更多。

If you want to get a feel for explain , then use tables with a few tens of thousands of rows. 如果您希望获得explain的感觉,请使用具有几万行的表。

You seem to be asking about EXPLAIN , INDEXing , and optimizing particular SELECTs . 您似乎在询问EXPLAININDEXing和优化特定的SELECTs

For this: 为了这:

select  u.name
    from  users as u
    join  accounts as a on u.id = a.user_id
    where  a.amount > 1000;

the optimizer will pick between users and accounts for which table to look at first. 优化器将在usersaccounts之间选择首先要查看的表。 Then it will repeatedly reach into the other table. 然后它将反复到达另一个表。

  1. Since you say a.amount > ... but nothing about u , the optimizer is very likely to pick a first. 既然你说a.amount > ...但无事u ,优化很可能挑选a第一。

  2. If a.amount > 1000 is selective enough (less than, say, 20% of the rows) and there is INDEX(amount) , it will use that index. 如果a.amount > 1000足够有选择性(少于行的20%) 并且INDEX(amount) ,它将使用该索引。 Else it will do a table scan of a . 否则,它会做的表扫描a

  3. To reach into u , it needs some index starting with id . 要进入u ,它需要一些以id开头的索引。 Keep in mind that a PRIMARY KEY is an index. 请记住, PRIMARY KEY 索引。

This, and many more basics, are covered in my index cookbook . 我的索引菜谱涵盖了这一点以及更多基础知识。

See also myxlpain for a discussion of EXPLAIN . 另请参见myxlpainEXPLAIN讨论。

Please use SHOW CREATE TABLE ; 请使用SHOW CREATE TABLE ; it is more descriptive than DESCRIBE . 它比DESCRIBE更具描述性。

EXPLAIN FORMAT=JSON SELECT... is also somewhat cryptic, but it does have more details than a regular EXPLAIN . EXPLAIN FORMAT=JSON SELECT...还是有点神秘,但是它比常规EXPLAIN具有更多细节。

well, As your main filter has '>' comparison operator, it does full table scan Because it may or may not return all rows. 好吧,因为您的主过滤器具有“>”比较运算符,所以它可以进行全表扫描,因为它可能会或可能不会返回所有行。

as you join the 'accounts' table with 'user_id' column, it shows the 'user_id' index in Possible Keys, but it doesn't use it, because of the FULL TABLE SCAN process. 当您将带有“ user_id”列的“ accounts”表结合在一起时,它会在“可能的键”中显示“ user_id”索引,但是由于FULL TABLE SCAN进程,它没有使用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM