MySQL查询需要很长时间。我尝试了许多查询的变体,但似乎没有任何东西影响查询速度
以下是我目前的查询和结构数据:MySQL查询需要很长时间。我尝试了许多查询的变体,但似乎没有任何东西影响查询速度,mysql,sql,join,Mysql,Sql,Join,以下是我目前的查询和结构数据: SELECT * FROM gmm_sql as a LEFT JOIN usds as b ON a.dp_id = b.dp_id LEFT JOIN usdsown as c ON b.dp_id = c.dp_id WHERE a.comm like '%tree%' gmm_sql:21个字段。所有字段varchar从20到255混合。4882项记录。 usds:7块地。所有字段varchar从20到255混合。304713
SELECT *
FROM gmm_sql as a
LEFT JOIN usds as b ON a.dp_id = b.dp_id
LEFT JOIN usdsown as c ON b.dp_id = c.dp_id
WHERE a.comm like '%tree%'
gmm_sql:21个字段。所有字段varchar从20到255混合。4882项记录。
usds:7块地。所有字段varchar从20到255混合。304713项记录。
播种:14块地。所有字段varchar从20到255混合。107606项记录。
我已经确认有手动匹配。我正在使用MySQL工作台运行这些查询测试。查询只会持续运行10分钟,不会停止
我做错什么了吗
以下是解释输出:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE a ALL NULL NULL NULL NULL 3973 Using where
1 SIMPLE b ALL dp_id NULL NULL NULL 304345
1 SIMPLE c ALL NULL NULL NULL NULL 105711
假设id字段已编制索引,这仍然可能是一个庞大的数据集。然后在带有通配符的varchar上有一个where子句。。。这将导致对整个结果集进行完整的表扫描,并否定a.comm字段上的任何索引
只是好奇,但是你能通过将select*改为'select counta.comm'并删除where子句来测试它吗。如果它仍然需要花费很长时间,那么它就是where子句,否则它就是结果集的构建。假设id字段被索引,这仍然可能是一个巨大的数据集。然后在带有通配符的varchar上有一个where子句。。。这将导致对整个结果集进行完整的表扫描,并否定a.comm字段上的任何索引 只是好奇,但是你能通过将select*改为'select counta.comm'并删除where子句来测试它吗。如果它仍然需要花费很长时间,那么它就是where子句,否则它就是结果集的构建。在gmm_sql.gmm上建立全文索引。+确保所有外键都已编入索引 其中,类似于“%tree%”的.comm是对数据进行的成本最高的操作。你有文字做全表扫描。普通索引不够,因为在匹配序列的开头有通配符 或者,如果您的数据库不支持这种类型的索引,您可以使用lucene或sphynx。在gmm_sql.gmm上创建全文索引。+确保所有外键都已编入索引 其中,类似于“%tree%”的.comm是对数据进行的成本最高的操作。你有文字做全表扫描。普通索引不够,因为在匹配序列的开头有通配符
或者,如果您的数据库不支持这种类型的索引,您可以使用lucene或sphynx。我看到的第一个争论点是:
WHERE a.comm like '%tree%'
即使在GMM_SQL.comm上有索引,对字符串左侧进行通配符也会使索引无效。虽然这是可行的,但它确实是搜索数据类型与字符串相关的内容的最差方法
全文搜索是在字符串中查找内容的首选方法。但是IIRC,MySQL仍然要求表是MyISAM
下一点是:
SELECT *
这将返回所有联接表中的所有列。SELECT子句应仅包含实际需要的列,因为:
您返回的数据比需要的多
数据类型确实会影响性能,例如:如果其中一列是很长的字符串,或者是二进制/二进制数据
第三,你的加入标准。数据类型越小,查询速度越快。我假设任何id为INT的东西都意味着INT。如果不需要,就不要使用BIGINT。我看到的第一个争论点是:
WHERE a.comm like '%tree%'
即使在GMM_SQL.comm上有索引,对字符串左侧进行通配符也会使索引无效。虽然这是可行的,但它确实是搜索数据类型与字符串相关的内容的最差方法
全文搜索是在字符串中查找内容的首选方法。但是IIRC,MySQL仍然要求表是MyISAM
下一点是:
SELECT *
这将返回所有联接表中的所有列。SELECT子句应仅包含实际需要的列,因为:
您返回的数据比需要的多
数据类型确实会影响性能,例如:如果其中一列是很长的字符串,或者是二进制/二进制数据
第三,你的加入标准。数据类型越小,查询速度越快。我将假设任何id都意味着INT。如果不需要,请不要使用BIGINT。如果字段都是var_字符,那么这可能不是一个好的设计。您是否创建了任何索引?请在您的问题后附加一个EXPLAIN的输出,以便查询:我首先查看EXPLAIN输出。如果在那些dp_id列上没有索引,那么这些联接将非常昂贵。因此,在“like”开头的“%”比后面的时间要长得多。如果你颠倒了字段的内容,例如“eert”,你可以使用…像“eert%”这样的网站我在上面添加了解释输出。如果字段都是var_字符,那可能不是好的设计。您是否创建了任何索引?请在您的问题后附加一个EXPLAIN的输出,以便查询:我首先查看EXPLAIN输出。那些工作
如果在那些dp_id列上没有索引,那么ns将非常昂贵。因此,在“like”开头的“%”比后面的时间要长得多。如果你颠倒了字段的内容,例如“eert”,你可以使用…像“eert%”这样的网站,我在上面添加了解释输出。