MySQL“;“发送数据”;慢得可怕

MySQL“;“发送数据”;慢得可怕,sql,mysql,Sql,Mysql,我有一个中等大小的表,目前有277k条记录,我正在尝试对其进行全文搜索。在到达发送数据阶段之前,搜索似乎非常快 表格: 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`), FULL

我有一个中等大小的表,目前有277k条记录,我正在尝试对其进行
全文搜索。在到达发送数据阶段之前,搜索似乎非常快

表格:

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
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
查询:

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
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
个人资料:(我删掉了看似无用的信息)

description
看起来很棒,简单的一行: 描述:

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
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
app中看到了类似的性能,它们都连接到
localhost

更新:

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
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
  • 根据请求平均行大小的注释,它是:53.8485
  • 根据注释,这里是上面描述的
description
看起来很棒,简单的一行代码

因为在查询中只使用一个表,所以它只能是一行

但是,您的查询不使用
全文
索引

为了使索引可用,您应该稍微重写查询:

SELECT  *
FROM    sqinquiries_inquiry
WHERE   MATCH (names, emails) AGAINST ('smith' IN BOOLEAN MODE)
ORDER BY
        id DESC
LIMIT 100
MATCH
仅当与定义索引的精确列集进行匹配时才使用索引

因此,您的查询在
id
上使用索引扫描:
使用索引;在
描述的末尾使用where

发送数据
非常容易引起误解:这实际上是上一个操作结束和当前操作结束之间经过的时间

例如,我刚刚运行了以下查询:

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.
编辑以删除下一票:)

我认为通过缓慢的网络连接传输大量数据

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

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


一些客户端支持结果数据包的压缩。也许你想看看这个。

你正在检索的数据量有多大?如果您不知道,请查看表中的统计信息,告诉我们平均行大小。我们不确定如何计算平均行大小,因此我将此输出扔到了那里:
选择AVG(长度(名称)+长度(电子邮件)+长度(id)+长度(ts))作为sqinquires\u inquires的AVG\u长度
。如果有更好的方法,请告诉我。问题是没有使用您的
全文键。请您发布
描述
?好的,您的
全文键
未被使用,而
主键
用于排序。重写我的帖子中的查询。这是从localhost运行的,只返回100个结果,大多数结果是1个电子邮件地址和一个名称。数据量不大,连接速度也不慢。我使用的是5.1.35版。为什么索引不可用?
@Jack M.
:我的帖子解释了原因。在我阅读时,它没有更新以包含您的编辑,现在我似乎无法实际将其更改为向上投票。
@Jack M.
:先单击向下箭头删除向下投票,然后单击向上投票。“投票太旧,无法更改,除非此答案已编辑。”. 对杰夫大喊大叫。=-]