MySQL“发送数据”非常慢

时间:2009-09-18 16:24:42

标签: sql mysql

我有一张中等大小的表,目前有277k条记录,我正在尝试进行FULLTEXT搜索。搜索似乎非常快,直到它进入发送数据阶段。

表:

CREATE TABLE `sqinquiries_inquiry` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `ts` datetime NOT NULL,
  `names` longtext NOT NULL,
  `emails` longtext NOT NULL,
  PRIMARY KEY (`id`),
  FULLTEXT KEY `sqinquiries_inquiry_search` (`names`,`emails`)
) ENGINE=MyISAM AUTO_INCREMENT=305560 DEFAULT CHARSET=latin1

查询:

SELECT * FROM `sqinquiries_inquiry` WHERE (
  MATCH (`sqinquiries_inquiry`.`names`) AGAINST ('smith' IN BOOLEAN MODE) OR
  MATCH (`sqinquiries_inquiry`.`emails`) AGAINST ('smith' IN BOOLEAN MODE)
) ORDER BY `sqinquiries_inquiry`.`id` DESC LIMIT 100

个人资料:(我剪掉了看似无用的信息)

+-------------------------+----------+
| Status                  | Duration |
+-------------------------+----------+
| preparing               | 0.000014 | 
| FULLTEXT initialization | 0.000015 | 
| executing               | 0.000004 | 
| Sorting result          | 0.000008 | 
| Sending data            | 2.247934 | 
| end                     | 0.000011 | 
| query end               | 0.000003 | 
+-------------------------+----------+

DESCRIBE看起来很棒,简单的一个班轮: 描述:

id: 1
select_type: SIMPLE
table: sqinquiries_inquiry
type: index
possible_keys: NULL
key: PRIMARY
key_len: 4 
ref: NULL
rows: 100
Extra: Using where

所以我不明白的是2.25秒的发送数据来自哪里?我在Python和控制台mysql应用中看到类似的性能,都连接到localhost

更新

  • 每条评论请求平均行数,为:53.8485
  • 根据评论,这是上面的DESCRIBE

2 个答案:

答案 0 :(得分:32)

  

DESCRIBE看起来很棒,只是一个简单的衬垫。

由于您在查询中仅使用一个表,因此除了单行之外,它不能是任何其他表。

但是,您的查询不使用FULLTEXT索引。

要使索引可用,您应该稍微重写一下查询:

SELECT  *
FROM    sqinquiries_inquiry
WHERE   MATCH (names, emails) AGAINST ('smith' IN BOOLEAN MODE)
ORDER BY
        id DESC
LIMIT 100

MATCH仅在您与定义索引的确切列集匹配时才使用索引。

因此,您的查询会在id的最后Using index; Using where DESCRIBE上使用索引扫描。

Sending data具有误导性:这实际上是在上一个操作结束和当前操作结束之间经过的时间。

例如,我刚刚运行了这个查询:

SET profiling = 1;

SELECT  *
FROM    t_source
WHERE   id + 1 = 999999;

SHOW PROFILE FOR QUERY 39;

返回了一行和此个人资料:

'starting', 0.000106
'Opening tables', 0.000017
'System lock', 0.000005
'Table lock', 0.000014
'init', 0.000033
'optimizing', 0.000009
'statistics', 0.000013
'preparing', 0.000010
'executing', 0.000003
'Sending data', 0.126565
'end', 0.000007
'query end', 0.000004
'freeing items', 0.000053
'logging slow query', 0.000002
'cleaning up', 0.000005

由于索引不可用,MySQL需要执行全表扫描。

0.126565秒是从执行开始(读取第一行的时间)到执行结束(最后一行被发送到客户端的时间)的时间。

最后一行位于表格的最后,需要很长时间才能找到并发送。

P. S.编辑删除了downvote:)

答案 1 :(得分:-8)

我认为您通过慢速网络连接传输大量数据。

而不是选择*只选择您真正需要的列。

如果您的表包含要在结果中显示的大型文本字段,则可以使用子字符串仅传输文本的前几个字符/单词。

某些客户端支持压缩结果包。也许yxou想看一看。