首页 > 解决方案 > 使用复杂查询加快搜索分页

问题描述

我正在开发一个带有底层 MySQL 数据库的 API。

我有一些涉及多个连接的复杂查询,其中一些表很大(> 2 亿行)。

我通过根据 uid 对查询结果进行排序并在最后一个 uid 之后获取页面来使用搜索分页。

对于大多数查询,这非常快,但是如果查询返回一个页面上的 uids 有很大跳跃的集合,这将变得非常慢。

例如,如果第一页返回 uids 1、2、3、4 和 5,它的速度非常快,但如果查询返回 uids 1、2、3 50000000 和 50000001,则查询变得非常慢(约 100 秒)。

有什么想法可以加快速度吗?

这是一个复杂的查询,它周围的表结构和索引:

>Q1 (fast if there is no jump in h.uid)
SELECT STRAIGHT_JOIN *
FROM h use index(ix_join) JOIN r ON r.uid = h.rID JOIN so ON so.uid = h.soID 
JOIN e ON e.uid = h.eID JOIN sa ON sa.uid = h.saID 
WHERE r.chr = '2' AND r.r1 >= 99999999 AND r.r2 <= 103000000 AND r.bin
IN (0, 2, 20, 21, 168, 169, 170, 171, 1347, 1348, 1349, 1350, 1351, 1352, 1353, 1354, 1355, 1356, 1357, 1358, 1359, 1360, 1361, 1362, 1363, 1364, 1365, 1366, 1367, 1368, 1369, 1370) 
AND h.uid > 77178 ORDER BY h.uid
LIMIT 1000

>explain Q1
id|select_type|table |type  |possible_keys             |key    |key_len|ref         |rows     |Extra                      |
--|-----------|------|------|--------------------------|-------|-------|------------|---------|---------------------------|
 1|SIMPLE     |h     |ALL   |ix_join                   |       |       |            |162690954|Using where; Using filesort|
 1|SIMPLE     |r     |eq_ref|PRIMARY,ix_uid,ix_bin_chr |PRIMARY|4      |hg38.h.rID  |        1|Using where                |
 1|SIMPLE     |so    |eq_ref|PRIMARY,ix_uid            |PRIMARY|4      |hg38.h.soID |        1|                           |
 1|SIMPLE     |e     |eq_ref|PRIMARY,ix_uid            |PRIMARY|4      |hg38.h.eID  |        1|                           |
 1|SIMPLE     |sa    |eq_ref|PRIMARY,ix_uid            |PRIMARY|4      |hg38.h.saID |        1|                           |

>Q2 (takes about 15s regardless of jumps in h.uid)
SELECT *
FROM h use index(ix_join) JOIN r ON r.uid = h.rID JOIN so ON so.uid = h.soID 
JOIN e ON e.uid = h.eID JOIN sa ON sa.uid = h.saID 
WHERE r.chr = '2' AND r.r1 >= 99999999 AND r.r2 <= 103000000 AND r.bin
IN (0, 2, 20, 21, 168, 169, 170, 171, 1347, 1348, 1349, 1350, 1351, 1352, 1353, 1354, 1355, 1356, 1357, 1358, 1359, 1360, 1361, 1362, 1363, 1364, 1365, 1366, 1367, 1368, 1369, 1370) 
AND h.uid > 77178 ORDER BY h.uid
LIMIT 1000

>explain Q2
id|select_type|table |type  |possible_keys             |key         |key_len|ref         |rows  |Extra                                                              |
--|-----------|------|------|--------------------------|------------|-------|------------|------|-------------------------------------------------------------------|
 1|SIMPLE     |r     |range |PRIMARY,ix_uid,ix_bin_chr |ix_bin_chr  |19     |            |494112|Using index condition; Using where; Using temporary; Using filesort|
 1|SIMPLE     |h     |ref   |ix_join                   |ix_join     |4      |hg38.r.uid  |     1|Using index condition                                              |
 1|SIMPLE     |so    |eq_ref|PRIMARY,ix_uid            |PRIMARY     |4      |hg38.h.soID |     1|                                                                   |
 1|SIMPLE     |e     |eq_ref|PRIMARY,ix_uid            |PRIMARY     |4      |hg38.h.eID  |     1|                                                                   |
 1|SIMPLE     |sa    |eq_ref|PRIMARY,ix_uid            |PRIMARY     |4      |hg38.h.saID |     1|                                                                   |

>desc h
Field       |Type            |Null|Key|Default|Extra         |
------------|----------------|----|---|-------|--------------|
uid         |int(10) unsigned|NO  |PRI|       |auto_increment|
type        |varchar(25)     |NO  |   |       |              |
score       |float           |YES |   |       |              |
peak        |int(11)         |YES |   |       |              |
rID         |int(10) unsigned|NO  |MUL|       |              |
saID        |int(10) unsigned|NO  |MUL|       |              |
eID         |int(10) unsigned|NO  |MUL|       |              |
soID        |int(10) unsigned|NO  |MUL|       |              |

Table |Non_unique|Key_name    |Seq_in_index|Column_name |Collation|Cardinality|Sub_part|Packed|Null|Index_type|
------|----------|------------|------------|------------|---------|-----------|--------|------|----|----------|
h     |         0|PRIMARY     |           1|uid         |A        |  162690954|        |      |    |BTREE     |
h     |         1|ix_join     |           1|rID         |A        |  162690954|        |      |    |BTREE     |
h     |         1|ix_join     |           2|saID        |A        |  162690954|        |      |    |BTREE     |
h     |         1|ix_join     |           3|eID         |A        |  162690954|        |      |    |BTREE     |
h     |         1|ix_join     |           4|so ID       |A        |  162690954|        |      |    |BTREE     |

>desc r
Field|Type                |Null|Key|Default|Extra         |
-----|--------------------|----|---|-------|--------------|
uid  |int(10) unsigned    |NO  |PRI|       |auto_increment|
bin  |smallint(5) unsigned|NO  |MUL|       |              |
chr  |varchar(5)          |NO  |MUL|       |              |
r1   |int(10) unsigned    |NO  |   |       |              |
r2   |int(10) unsigned    |NO  |   |       |              |

Table  |Non_unique|Key_name    |Seq_in_index|Column_name|Collation|Cardinality|Sub_part|Packed|Null|Index_type|
-------|----------|------------|------------|-----------|---------|-----------|--------|------|----|----------|
r      |         0|PRIMARY     |           1|uid        |A        |  217539807|        |      |    |BTREE     ||
r      |         1|ix_uid      |           1|uid        |A        |  217539807|        |      |    |BTREE     |
r      |         1|ix_bin_chr  |           1|bin        |A        |         18|        |      |    |BTREE     |
r      |         1|ix_bin_chr  |           2|chr        |A        |     103491|        |      |    |BTREE     |

>desc sa 
Field    |Type                |Null|Key|Default|Extra         |
---------|--------------------|----|---|-------|--------------|
uid      |int(10) unsigned    |NO  |PRI|       |auto_increment|
name     |varchar(250)        |NO  |MUL|       |              |

Table  |Non_unique|Key_name                     |Seq_in_index|Column_name|Collation|Cardinality|Sub_part|Packed|Null|Index_type|
-------|----------|-----------------------------|------------|-----------|---------|-----------|--------|------|----|----------|
sa     |         0|PRIMARY                      |           1|uid        |A        |        574|        |      |    |BTREE     |
sa     |         1|ix_name                      |           1|name       |A        |        574|        |      |    |BTREE     |

>desc so
Field              |Type            |Null|Key|Default|Extra         |
-------------------|----------------|----|---|-------|--------------|
uid                |int(10) unsigned|NO  |PRI|       |auto_increment|
name               |varchar(250)    |NO  |MUL|       |              |
so_metadata        |varchar(250)    |YES |   |       |              |
metadata_descriptor|varchar(250)    |YES |   |       |              |
url                |varchar(250)    |YES |   |       |              |
insert_date        |datetime        |NO  |   |       |              |

Table  |Non_unique|Key_name|Seq_in_index|Column_name        |Collation|Cardinality|Sub_part|Packed|Null|Index_type|
-------|----------|--------|------------|-------------------|---------|-----------|--------|------|----|----------|
so     |         0|PRIMARY |           1|uid                |A        |       2161|        |      |    |BTREE     |
so     |         1|ix_name |           1|name               |A        |         24|        |      |    |BTREE     |

>desc e

Field              |Type            |Null|Key|Default|Extra         |
-------------------|----------------|----|---|-------|--------------|
uid                |int(10) unsigned|NO  |PRI|       |auto_increment|
name               |varchar(250)    |NO  |MUL|       |              |
e_metadata         |varchar(250)    |YES |   |       |              |
metadata_descriptor|varchar(250)    |YES |   |       |              |

Table      |Non_unique|Key_name|Seq_in_index|Column_name        |Collation|Cardinality|Sub_part|Packed|Null|Index_type|
-----------|----------|--------|------------|-------------------|---------|-----------|--------|------|----|----------|
e          |         0|PRIMARY |           1|uid                |A        |          6|        |      |    |BTREE     |
e          |         1|ix_name |           1|name               |A        |          6|        |      |    |BTREE     |

标签: mysqlsql

解决方案


推荐阅读