【问题标题】:How to make my query selection faster over a 2 million records如何使我的查询选择更快超过 200 万条记录
【发布时间】:2014-08-10 18:44:56
【问题描述】:

在这里,我需要解决我的问题。我有一个包含 200 万条与地理坐标相关的记录的表。要从表中获取特定行,查询执行时间为 24 秒。在这里,我想要为我的应用程序方面选择超过 500 条记录。因此,请任何人提出任何解决方案以使我的查询更快。

查询

SELECT * FROM myProject.MAP where start_ip<=419297593 and end_ip>=419297593;

表格结构

Field,Type,Null,Key,Default,Extra
start_ip,"int(10) unsigned",YES,MUL,NULL,
end_ip,"int(10) unsigned",YES,MUL,NULL,
country_id,int(11),NO,,NULL,
lat,double,YES,,NULL,
lng,double,YES,,NULL,
id,int(11),NO,PRI,NULL,auto_increment

【问题讨论】:

  • 显示您的一些查询,以便每个人都可以轻松调整您的查询
  • @PandiyanCool 添加了查询
  • @AnkitBajpai 我想从中选择一个特定的行。我怎样才能将我的选择限制在 500 上。
  • start_ipend_ip 上创建索引。这应该会加快速度。
  • 也贴一下表结构(即表上存在哪些数据类型和索引)

标签: java mysql sql hql mysql-workbench


【解决方案1】:

您需要在 start_ipend_ip 列上创建索引。有关语法和不同类型的索引,请查看documentation

CREATE INDEX id_index ON myproject.MAP (start_ip);

如 cmets 中所述,Visual Explain 还可以帮助您确定如何改进查询。您可以比较添加索引前后的两个解释,看看它们有何不同。

【讨论】:

  • 使用 Workbench 中的解释(和视觉解释)功能来帮助确定如何改进此查询。正如 Ean 建议的那样,添加这些索引,您会注意到解释计划发生了变化。研究说明和索引以获取更多信息。
  • use-the-index-luke.com 是学习索引和调优的一个很好的免费资源。它也有不同数据库的示例。
  • 对于单个值查询执行速度很快...但是选择超过 20 个值再次花费太多时间...每个查询都需要事务开始时间:1403241044326 毫秒事务结束时间:1403241077426 毫秒.总耗时:54315 m/s
  • @AravindCheekkallur 选择超过 20 个值是什么意思?
  • @Ean 这里将 ip 转换为数字,然后使用该数字执行查询。索引后,单个数字看起来更快。但我有超过100 ips。现在查询变慢了
【解决方案2】:

对于这个特定的查询,我建议使用如下复合索引:

CREATE INDEX map_ix1 ON myproject.MAP (end_ip, start_ip);

如果这是一个独特的组合,create unique index ...

另外,不要在查询中使用 *。如果您需要所有列,最好(为了可维护性)显式声明这些列。您还可以考虑使用覆盖索引(包含查询中访问的所有列的索引):

CREATE INDEX map_ix1 ON myproject.MAP (end_ip, start_ip, ...);

【讨论】:

  • 合成索引和其他索引有什么显着区别吗?我尝试了@Ean 发布的内容..但超过 20 个值仍然很慢。
  • 一个复合索引(查询中使用了所有列)几乎总是比几个单列索引好。
  • 谢谢,我也会尝试这个。要创建复合索引,我可以从该表中删除已添加的索引。或者它会自动删除
  • 您在查询中使用了哪些列?您可能想尝试像 (end_ip, start_ip, ) 这样的索引
  • 好的,您可能希望在索引末尾包含这些内容。我还建议降低 start_ip,例如:CREATE INDEX map_ix1 ON myproject.MAP (end_ip, start_ip desc, lat, lng, county_id)。它应该比 start_ip 上的单列索引执行得更好
【解决方案3】:

您的查询似乎是错误的:为什么要将 IP 地址作为数值与任何内容进行比较? IP 地址不是您可以有意义地比较的东西。

但是,由于您已经在使用地图数据(因为您有 lat、long 等),这意味着您应该使用空间扩展。好消息是空间索引允许您非常有效地执行这种精确类型的查询。您应该已经在(lat, long) 上创建了空间索引,或者使用(lat, long) 作为复合类型POINT - 这允许您快速执行基于坐标的搜索。

如果您仍想比较 IP 地址,您可以将元组 (start_ip, end_ip) 视为空间 POINT 并执行搜索属于您指定范围的该点。这将为您提供最大的性能。您可以阅读更多关于空间扩展的信息here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-01-06
    • 1970-01-01
    • 2019-10-27
    • 2014-07-09
    • 2013-11-02
    • 1970-01-01
    • 1970-01-01
    • 2017-12-30
    相关资源
    最近更新 更多