2013-02-21 67 views
1

我有一个mysql slow.log输出的问题。 慢查询mysql显示这一点,我检查了与mysql explain相同,它说只有5行被检查,但mysql缓慢说,大约7 lkh行被检查。了解slow.log mysql

另外我的查询中也没有地方写set timestamp

# [email protected]: dba[dba] @ localhost [] 
    # Query_time: 7.282718 Lock_time: 1.291532 Rows_sent: 0 Rows_examined: 651223 
    SET timestamp=1361437845; 
    SELECT * 
    FROM tableA 
    WHERE app='pic' and sub 
    LIKE '%katrina%' 
    order by id desc limit 5 

这里是解释输出

1 SIMPLE tableA index NULL PRIMARY 4 NULL 5 Using where 
+0

你可以发布结果你的解释说明吗? – ESG 2013-02-21 15:58:47

+0

@TheVedge 1 \t SIMPLE \t TABLEA \t指数\t NULL \t PRIMARY NULL 使用其中 – wayenjoy 2013-02-21 16:09:31

回答

3

你刚才5行,因为你限制的结果设置为5行。查看查询的最后一行。仍然MySQL必须检查那些651223行以查找从中只显示5行的结果集。这是因为您的LIKE子句以%开头,因此在列sub上不能使用索引。如果您在app列上有索引,则可能因以下原因而无法使用。也许你的表格所保留的行数与你的表的数量相比太少了。所以MySQL决定使用主键索引进行排序(您的order by子句)。至少我是这么认为的,因为我无法真正阅读你的评论中的explain结果。下次请将这些信息编辑到问题中。

SET timestamp=1361437845是查询作为unix_timestamp执行的时间。

UPDATE(进一步说明):

你LIKE子句LIKE '%katrina%'。这意味着“字符串中的某个地方是卡特里娜,在它之前和之后可能会有字符”。现在想象你自己,你想根据这些标准在电话簿中找人。事实上,电话簿是按字母顺序排列的,因为人名可能是Ankatrina或Zekatrina。与您的索引在列sub上相同。

想象一下,你有300万行,其中100万行的列应用中有“pic”,100万有“nic”,100万有“asdf”。这意味着,看起来实际上是额外的工作,然后查看表中的实际记录。所以有时只是扫描整个桌子便宜些。但就像我说的那样,这只是一个猜测。我们没有足够的关于数据库的信息。

拥有索引并不能保证索引将被使用。

EXPLAIN说5行但不是slow-query-log的原因是,那EXPLAIN实际上只是一个猜测,优化程序如何处理您的查询。当你想知道如何处理它,使用EXPLAIN EXTENDED。这里还有一个棘手的问题是,如果你不想检查这么多的行,那么查询就不需要ORDER BY id DESC。然后,由于你的LIMIT 5,MySQL只会扫描5行并吐出结果。由于你的订单,它可能必须首先创建一个临时表,对事物进行排序,然后从该表中分出5行。可能是这在EXPLAIN中没有考虑,但在slow-query-log

+0

我有子指标以及应用程序,所以我觉得应该用index.one点我没有得到。你是说:“你只有5行,因为你将结果集限制为5行”我已经在mysql以及脚本中使用了这个查询.mysql解释说只有5行,但slow.log说约7万? ?? /据我所知mysql解释给出近乎完美的输出 – wayenjoy 2013-02-21 17:51:31

+0

@wayenjoy更新了我的答案。 – fancyPants 2013-02-21 18:04:35

+0

享受阅读你的解释谢谢。你的建议。我必须显示搜索,如果我不会使用%它不会显示正确的搜索,因为我们不知道用户是否会按照您的搜索建议我会通过ID删除命令,但我认为它会搜索整个数据库 – wayenjoy 2013-02-21 18:20:21