我有一张中等大小的表,目前有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
。
更新
DESCRIBE
。答案 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想看一看。