优化sql查询

优化sql查询,sql,mysql,optimization,Sql,Mysql,Optimization,是否可以优化此查询 SELECT count(locId) AS antal , locId FROM `geolitecity_block` WHERE (1835880985>= startIpNum AND 1835880985 <= endIpNum) OR (1836875969>= startIpNum AND 1836875969 <= endIpNum) OR (1836878754>= startIpNum AND 18368787

是否可以优化此查询

SELECT count(locId) AS antal , locId 
FROM `geolitecity_block` 
WHERE (1835880985>= startIpNum AND 1835880985 <= endIpNum) 
  OR (1836875969>= startIpNum AND 1836875969 <= endIpNum) 
  OR (1836878754>= startIpNum AND 1836878754 <= endIpNum)
  ...
  ... 
  OR (1843488110>= startIpNum AND 1843488110 <= endIpNum)
GROUP BY locId ORDER BY antal DESC LIMIT 100
更新 explain查询如下所示

CREATE TABLE IF NOT EXISTS `geolitecity_block` (
  `startIpNum` int(11) unsigned NOT NULL,
  `endIpNum` int(11) unsigned NOT NULL,
  `locId` int(11) unsigned NOT NULL,
  PRIMARY KEY (`startIpNum`),
  KEY `locId` (`locId`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+----+-------------+-------------------+-------+---------------+-------+---------+------+------+----------------------------------------------+
| id | select_type | table             | type  | possible_keys | key   | key_len | ref  | rows | Extra                                        |
+----+-------------+-------------------+-------+---------------+-------+---------+------+------+----------------------------------------------+
|  1 | SIMPLE      | geolitecity_block | index | PRIMARY       | locId | 4       | NULL |  108 | Using where; Using temporary; Using filesort |
+----+-------------+-------------------+-------+---------------+-------+---------+------+------+----------------------------------------------+

要优化性能,请在startIpNum和endIpNum上创建索引

在geolitecity区块(startIpNum)上创建索引索引; 在geolitecity_区块上创建索引_endIpNum(endIpNum)


要优化性能,请在startIpNum和endIpNum上创建索引

在geolitecity区块(startIpNum)上创建索引索引; 在geolitecity_区块上创建索引_endIpNum(endIpNum)


对分组或排序的列进行索引几乎总能提高性能。我建议将此查询插入DTA(Database Tuning Advisor)以查看SQL是否可以提供任何建议,这可能包括在统计数据之外创建一个或多个索引。

对分组或排序的列进行索引几乎总能提高性能。我建议将此查询插入DTA(Database Tuning Advisor)以查看SQL是否可以提供任何建议,这可能包括在统计数据之外创建一个或多个索引。

如果在您的用例中可以,请创建一个临时表TMP\U结果(删除顺序)然后提交第二个查询,通过antal对结果进行排序。Filesort非常慢,在您的情况下,您无法避免此操作,因为您不按任何键/索引进行排序。要执行计数操作,必须扫描整个表。临时表是一种更快的解决方案


另外,在(startIpNum,endIpNum)上添加索引肯定会帮助您获得更好的性能,但是——如果您有很多行——这并不是一个很大的改进

如果在您的用例中可能的话,创建一个临时表TMP_RESULT(remove order),然后提交第二个查询,该查询通过antal对结果进行排序。Filesort非常慢,在您的情况下,您无法避免此操作,因为您不按任何键/索引进行排序。要执行计数操作,必须扫描整个表。临时表是一种更快的解决方案


另外,在(startIpNum,endIpNum)上添加索引肯定会帮助您获得更好的性能,但是——如果您有很多行——这并不是一个很大的改进

让一个存储过程进行多次调用并返回,因为完整表扫描将破坏您的性能。也许,您可以向我们展示解释计划吗?@Piskvor,这是解释查询让一个存储过程进行多次调用并返回,因为完整表扫描将破坏您的性能。也许,你能给我们看一下解释计划吗?@Piskvor,这是解释问题我应该在startIpNum上添加索引,即使它是主要的吗?我应该在startIpNum上添加索引,即使它是主要的吗?