回答

收藏

MySQL``结束数据''的速度非常慢

技术问答 技术问答 341 人阅读 | 0 人回复 | 2023-09-14

我有一个中等大小的表,目前有277k条记录,我正在尝试对其进行FULLTEXT搜索。在进入“发送数据”阶段之前,搜索似乎非常快。
9 T+ i' }0 z7 b. Q3 F桌子:8 ~; ]: K2 u: Q
CREATE TABLE `sqinquiries_inquiry` (4 p7 W: @% \1 G8 G" ]0 D
  `id` int(11) NOT NULL AUTO_INCREMENT,
3 Y5 x% [: p$ z9 g/ h, m+ Q  `ts` datetime NOT NULL,* j6 B; n! F' n; B
  `names` longtext NOT NULL,
1 S- m9 @+ l+ R! O  `emails` longtext NOT NULL,
8 i! m4 c/ p, k7 P. p6 q  PRIMARY KEY (`id`),7 Z( i# t# T0 y. p. s( b
  FULLTEXT KEY `sqinquiries_inquiry_search` (`names`,`emails`)
5 [8 U* n' |- u: c& N) ENGINE=MyISAM AUTO_INCREMENT=305560 DEFAULT CHARSET=latin1
5 g- q' w+ x: G查询:
, |* M  S; N/ T, v: P6 V6 J. qSELECT * FROM `sqinquiries_inquiry` WHERE (' C0 j' A& b" z/ u2 |# f! K* j
  MATCH (`sqinquiries_inquiry`.`names`) AGAINST ('smith' IN BOOLEAN MODE) OR
% g9 [  @8 A/ S& Q  MATCH (`sqinquiries_inquiry`.`emails`) AGAINST ('smith' IN BOOLEAN MODE)6 G" F- x" u* m8 Y$ |
) ORDER BY `sqinquiries_inquiry`.`id` DESC LIMIT 100& Q) I6 s5 u$ Z8 X0 U
个人资料:( 我删除了看似无用的信息)# T9 |! M( K# g# Z% W
+-------------------------+----------+1 X; B! S0 U! _+ s
| Status                  | Duration |
3 V$ U; H7 _% Y, G+-------------------------+----------+
/ A8 {$ Z' T. g0 n; ?: f6 i| preparing               | 0.000014 |
( p/ u7 k) l- j5 n5 f. `| FULLTEXT initialization | 0.000015 | 1 y' ^8 h( A4 B+ z. W
| executing               | 0.000004 | + y6 K0 n! J6 _9 C. a5 B
| Sorting result          | 0.000008 | ! j6 t: O  N& m
| Sending data            | 2.247934 | 7 L1 g- }- s' T: v
| end                     | 0.000011 |
3 u9 n& B) n! \  h& K8 ?7 Q| query end               | 0.000003 |
, L- M2 H! t- x  }9 Y! m+-------------------------+----------+3 x5 [. s) n0 p+ S- y& p! T. G  Y0 l
在DESCRIBE看起来不错,一个简单的内衬: 该描述:
/ X+ r; l. H; {id: 1
$ O; f; Q$ Q( T+ Q9 b8 lselect_type: SIMPLE
: v7 ]* }6 n3 o, ]4 x' S. X9 X3 htable: sqinquiries_inquiry* l' G" N$ U- {% h5 _
type: index, J7 t0 a- l0 D/ a- }
possible_keys: NULL! ~5 K, Y9 t7 a4 Z
key: PRIMARY# J# E0 t& {7 I: Q4 s5 R
key_len: 4 ( c4 Y/ }- Q$ X9 f2 I/ W/ B/ g# _: `9 R
ref: NULL) }; I" J1 R+ N6 ]
rows: 1003 d; \1 F7 h8 @2 u. |
Extra: Using where! l# p/ o! c) y; T; V! a
因此,我不了解的是2.25秒的发送数据来自何处?我在Python和控制台mysql应用程序中都看到了类似的性能,两者都连接到localhost。- }0 \& `5 H1 M1 |' j
更新:1 y/ d8 M9 y( U1 G
每个请求平均行大小的注释为:53.8485. L9 l7 @$ R# g' \" u: ^
根据评论,这是DESCRIBE上面的内容。6 L) l0 s% |$ n" U: O! z
9 T0 h, ?, O7 n. Q4 N# H
               
$ |/ B( y  Z6 ?* K* d$ a解决方案:
$ Q& v3 n# {/ x8 H# i               
2 i2 B8 |8 l' r; S8 O* `9 O1 q- `0 O6 Q: b4 P
/ ~. A/ R5 ]4 u9 E3 H, a
               
0 @( c: A1 X$ w7 `# p. E在DESCRIBE看起来不错,简单的一行。
( H0 y. T, C: |. H; L, B) y% g. I% j) G
由于您在查询中仅使用一个表,因此只能使用一个表。
# Q. p4 n9 o- A但是,您的查询不使用FULLTEXT索引。
2 u) A7 J  X8 |1 ]8 s$ o1 K为了使索引可用,您应该稍微重写一下查询:( A! o1 X# M' T' z
SELECT  *
: ~! m: f* s6 U: y% [. S2 hFROM    sqinquiries_inquiry
& v) V  ^6 d6 W. ~; q9 a# qWHERE   MATCH (names, emails) AGAINST ('smith' IN BOOLEAN MODE)
4 |( J' F* u/ L8 T! _$ u+ V; OORDER BY
4 d# G; }, O, p1 x* B( M: ^  g& f        id DESC
- \5 j$ d+ ^  j0 w. x7 f" G$ R2 ~/ QLIMIT 1005 D  ?9 V3 ]: m9 q* q: a
MATCH 仅当您与定义索引所在的确切列匹配时才使用索引。. W7 l/ ~+ c9 e7 B# {
所以,你的查询使用的索引扫描id:Using index; Using where在您的尽头DESCRIBE。
  f: r/ x9 R2 a& ]& k2 ^, Q$ USending data 这是很容易让人误解的:实际上,这是上一次操作结束到当前操作结束之间的时间。
' q5 E9 ?; w! \) W5 T* K( u例如,我只运行了以下查询:
5 v0 Y& p$ ~6 I: ]/ o* F+ M0 v) E' oSET profiling = 1;
& \5 ?$ k- c5 n: J: L9 lSELECT  *
& D/ Z# p1 c/ o' a- R9 W1 FFROM    t_source
1 w' A; f. K' h/ k/ |6 K- BWHERE   id + 1 = 999999;2 A, F% ~5 K+ }; d( }
SHOW PROFILE FOR QUERY 39;+ n0 p' u2 c2 F; t9 \) D
它返回了单行和此配置文件:2 S1 l) |4 v1 m: L
'starting', 0.000106
0 K# S* J3 a. [$ `. v'Opening tables', 0.000017
5 F# ~, B4 n* W) n; W0 K) ~; \4 u'System lock', 0.000005
) k; B8 C% r3 w4 Y: Z'Table lock', 0.000014# F" W. l0 Q3 G
'init', 0.000033
: M; N. u* J- u! O) Q2 f'optimizing', 0.000009' v! p/ C8 C. h/ r9 B4 M
'statistics', 0.000013! t* H. z& T/ Z4 G
'preparing', 0.000010
. ^$ z2 |2 R- |& F3 Z'executing', 0.0000033 p6 l  M" i0 N/ V& R; A) b
'Sending data', 0.126565
6 ^9 q/ L+ h$ q$ T% Z; [5 ~3 A$ n'end', 0.000007
7 g0 N9 _3 V' _5 ?3 f'query end', 0.0000049 I& }4 X" G6 U. h
'freeing items', 0.000053
8 p8 t. f  q2 H( I) |7 G'logging slow query', 0.000002
& @  d- {9 {" e$ S! J# R/ ]6 l'cleaning up', 0.000005
0 y: V$ w0 a1 ~由于索引不可用,因此MySQL需要执行全表扫描。
9 B6 X3 q+ A$ U" q9 \' J0.126565 秒是从执行开始(读取第一行的时间)到执行结束(从最后一行发送到客户端的时间)开始的时间。
) P3 N1 k1 U  h+ q% V+ S& H  p最后一行位于表的最末端,花了很长时间才找到并发送它。3 c8 h# o3 N" R% m8 \6 e; E
P. S. 编辑删除了downvote
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则