我需要帮助查询,这需要花费太多时间来检索数据。
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 |
+-----+-------------+----------+----------+---------------------------------------------------+-------------------+---------+----------------------------+------+----------------------------------------------+
你知道我在哪里看吗? 告诉我你是否需要更多元素
由于
答案 0 :(得分:1)
我认为EXPLAIN
输出相当直接地告诉你所有你需要知道的事情。
我看到索引用于JOINs
,但仅用于用于连接。我没有看到任何帮助重要条款,例如dataPro2.itemDefinitionId='PRO_NOM_EXERCICE'
。我还看到了一个“fullText”搜索,这可能是一种瘫痪。
我也没有看到用于“dataSet sid”的索引支持ON dataSet.sId=dataPro2.dataSetSid
。
简而言之,EXPLAIN
输出可能告诉所有人:你基本上是在进行暴力搜索,而候选行的数量可能真的很大。 (例如,如果sId/dataSetSid
字段不唯一,导致[部分]笛卡尔积产品情况。)
答案 1 :(得分:1)
“此查询返回大约28k行,但我将其限制为10”。 - 由于查询的结构方式(FULLTEXT
,LEFT
,ORDER 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*
。考虑其他选项以避免这种慢查询。