MySQL"发送数据"非常慢

Jac*_* M. 15 mysql sql

我有一张中等大小的桌子,目前有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
Run Code Online (Sandbox Code Playgroud)

查询:

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
Run Code Online (Sandbox Code Playgroud)

简介:( 我剪掉了看似无用的信息)

+-------------------------+----------+
| 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 | 
+-------------------------+----------+
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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

更新:

  • 每个评论请求平均行大小,它是:53.8485
  • 每条评论,DESCRIBE以上是这些.

Qua*_*noi 32

DESCRIBE看起来很大,一个简单的衬垫.

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

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

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

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

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;
Run Code Online (Sandbox Code Playgroud)

返回单行和此配置文件:

'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
Run Code Online (Sandbox Code Playgroud)

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

0.126565 秒是从执行(第一行被读出的时间),并且在执行(最后一行被发送到客户端的时间)的结束的开始的时间.

最后一行位于表的最后,查找和发送它需要很长时间.

P. S. 编辑删除downvote :)