选择orderBy&限制具有3,000,000行的表的速度

时间:2016-08-10 12:54:05

标签: mysql sql database performance indexing

我需要帮助查询,这需要花费太多时间来检索数据。

SELECT DISTINCT dataSet.professionalSid
FROM dataSet dataSet
INNER JOIN dataProfessional dataPro ON dataSet.sId=dataPro.dataSetSid
LEFT OUTER JOIN dataProfessional dataPro2  ON dataSet.sId=dataPro2.dataSetSid
AND (dataPro2.itemDefinitionId='PRO_NOM_EXERCICE'
     AND dataPro2.dataSetDefinitionId='DIRECTORY_PROFESSIONAL_RPPS')
WHERE dataSet.archive=0
  AND dataPro.dataSetDefinitionId='DIRECTORY_PROFESSIONAL_RPPS'
  AND (dataPro.itemDefinitionId IN ('PRO_PRENOM_EXERCICE'))
  AND MATCH(dataSet.searchIndex) AGAINST('+*p* ' IN BOOLEAN MODE)>=1
ORDER BY dataPro2.stringValue DESC LIMIT 10

表dataProfessional包含大约3.7m行,dataSet包含大约820,000行,其他表只包含表def,只包含5-10行。

此查询返回大约28k行,但我将其限制为10。

索引:

表数据集

+---------+------------+-----------------------------+--------------+--------------------------+-----------+-------------+----------+--------+------+------------+
|  Table  | Non_unique |          Key_name           | Seq_in_index |       Column_name        | Collation | Cardinality | Sub_part | Packed | Null | Index_type |
+---------+------------+-----------------------------+--------------+--------------------------+-----------+-------------+----------+--------+------+------------+
| dataSet |          0 | PRIMARY                     |            1 | sId                      | A         |      846564 | NULL     | NULL   |      | BTREE      |
| dataSet |          0 | sId                         |            1 | sId                      | A         |      846564 | NULL     | NULL   |      | BTREE      |
| dataSet |          1 | FK_dataSetDefinitionDataSet |            1 | dataSetDefinitionId      | A         |          70 | NULL     | NULL   |      | BTREE      |
| dataSet |          1 | FK_dataSetDefinitionDataSet |            2 | dataSetDefinitionVersion | A         |          76 | NULL     | NULL   |      | BTREE      |
| dataSet |          1 | FK_dataSetPatient           |            1 | patientSid               | A         |        2263 | NULL     | NULL   | YES  | BTREE      |
| dataSet |          1 | FK_dataSetProfessional      |            1 | professionalSid          | A         |      846564 | NULL     | NULL   | YES  | BTREE      |
| dataSet |          1 | FK_overrideDataSet          |            1 | overrideDataSetSid       | A         |           2 | NULL     | NULL   | YES  | BTREE      |
| dataSet |          1 | FullText                    |            1 | searchIndex              | NULL      |      846564 | NULL     | NULL   | YES  | FULLTEXT   |
+---------+------------+-----------------------------+--------------+--------------------------+-----------+-------------+----------+--------+------+------------+

表dataProfessional

+------------------+------------+-------------------------------+--------------+--------------------------+-----------+-------------+----------+--------+------+------------+
|      Table       | Non_unique |           Key_name            | Seq_in_index |       Column_name        | Collation | Cardinality | Sub_part | Packed | Null | Index_type |
+------------------+------------+-------------------------------+--------------+--------------------------+-----------+-------------+----------+--------+------+------------+
| dataProfessional |          0 | PRIMARY                       |            1 | sId                      | A         |     3636911 | NULL     | NULL   |      | BTREE      |
| dataProfessional |          0 | sId                           |            1 | sId                      | A         |     3636911 | NULL     | NULL   |      | BTREE      |
| dataProfessional |          1 | FK_dataSetDataPro             |            1 | dataSetSid               | A         |     1818455 | NULL     | NULL   |      | BTREE      |
| dataProfessional |          1 | FK_itemDefinitionDataPro      |            1 | itemDefinitionVersion    | A         |           2 | NULL     | NULL   |      | BTREE      |
| dataProfessional |          1 | FK_itemDefinitionDataPro      |            2 | itemDefinitionId         | A         |        8172 | NULL     | NULL   |      | BTREE      |
| dataProfessional |          1 | FK_dataProfessionalDataSetDef |            1 | dataSetDefinitionId      | A         |         952 | NULL     | NULL   |      | BTREE      |
| dataProfessional |          1 | FK_dataProfessionalDataSetDef |            2 | dataSetDefinitionVersion | A         |         952 | NULL     | NULL   |      | BTREE      |
| dataProfessional |          1 | stringValue                   |            1 | stringValue              | A         |      909227 | 10       | NULL   | YES  | BTREE      |
+------------------+------------+-------------------------------+--------------+--------------------------+-----------+-------------+----------+--------+------+------------+

这是查询的解释:

+-----+-------------+----------+----------+---------------------------------------------------+-------------------+---------+----------------------------+------+----------------------------------------------+
|  id | select_type |  table   |   type   |                   possible_keys                   |        key        | key_len |            ref             | rows |                    Extra                     |
+-----+-------------+----------+----------+---------------------------------------------------+-------------------+---------+----------------------------+------+----------------------------------------------+
|   1 | SIMPLE      | dataSet  | fulltext | PRIMARY   sId   FullText                          | FullText          |       0 |                            |    1 | Using where; Using temporary; Using filesort |
|   1 | SIMPLE      | dataPro  | ref      | FK_dataSetDataPro   FK_dataProfessionalDataSetDef | FK_dataSetDataPro |       8 | cloud_dev_eret.dataSet.sId |    2 | Using where; Distinct                        |
|   1 | SIMPLE      | dataPro2 | ref      | FK_dataSetDataPro   FK_dataProfessionalDataSetDef | FK_dataSetDataPro |       8 | cloud_dev_eret.dataSet.sId |    2 | Using where; Distinct                        |
+-----+-------------+----------+----------+---------------------------------------------------+-------------------+---------+----------------------------+------+----------------------------------------------+

你知道我在哪里看吗? 告诉我你是否需要更多元素

由于

2 个答案:

答案 0 :(得分:1)

我认为EXPLAIN输出相当直接地告诉你所有你需要知道的事情。

我看到索引用于JOINs,但仅用于用于连接。我没有看到任何帮助重要条款,例如dataPro2.itemDefinitionId='PRO_NOM_EXERCICE'。我还看到了一个“fullText”搜索,这可能是一种瘫痪。

我也没有看到用于“dataSet sid”的索引支持ON dataSet.sId=dataPro2.dataSetSid

简而言之,EXPLAIN输出可能告诉所有人:你基本上是在进行暴力搜索,而候选行的数量可能真的很大。 (例如,如果sId/dataSetSid字段不唯一,导致[部分]笛卡尔积产品情况。)

答案 1 :(得分:1)

“此查询返回大约28k行,但我将其限制为10”。 - 由于查询的结构方式(FULLTEXTLEFTORDER BY等),它必须在到达ORDER BY & LIMIT之前找到28K行。避免加快查询速度的唯一方法是缩小28K和/或加速单个部分。

请注意,EXPLAIN表示它以FULLTEXT索引开头,忽略其他索引。 通常这是'正确'的事情。但不是AGAINST('+*p* ' IN BOOLEAN MODE) - 这实际上是无用的。您基本上是在寻找searchIndex的{​​{1}}吗?这将是大部分的表格。但这需要额外的努力才能使用索引。

这会更快,但仍然不会很快:p

通过计算时间并查看它们是否得到相同的计数来测试我说的话:

searchIndex LIKE '%p%'

SELECT DISTINCT COUNT(*) FROM dataSet WHERE MATCH(dataSet.searchIndex) AGAINST('+*p* ' IN BOOLEAN MODE)>=1; SELECT DISTINCT COUNT(*) FROM dataSet WHERE searchIndex LIKE '%p%'; JOIN似乎毫无用处;它的目的是什么?

dataPro任何顺序都需要dataProfessional

INDEX(itemDefinitionId, dataSetDefinitionId, dataSetSid)可能只是LEFT JOIN吗?

用户是否生成了JOIN?考虑不允许这样做。考虑将其转换为我建议的*p*。考虑其他选项以避免这种慢查询。