首页 > 解决方案 > 如何索引和查询具有 60M 行和 50 列的非常大的数据库

问题描述

解释 SQL我有一个有 60M 行和 50 列的大表(列包括“company_idx”和“timestamp”)。因此,当我执行简单的 SQL 查询时,例如:

SELECT * FROM companies_Scores.Scores 
WHERE `company_idx`=11 
  AND `timestamp` BETWEEN  '"+start_date+" 00:00:00' AND '"+end_date+" 00:00:00'

运行基本上需要 4 分钟(这太长了)。因此,我考虑过索引我的表,所以我完成了:

CREATE INDEX idx_time ON companies_Scores.Scores(company_idx, timestamp) USING BTREE;

但是,当我现在执行以下操作时,也需要 4 分钟才能运行。

SELECT * FROM companies_Scores.Scores 
USE INDEX(idx_time) 
WHERE `company_idx`=11 
  AND `timestamp` BETWEEN  '"+start_date+" 00:00:00' AND '"+end_date+" 00:00:00'

我真的是 SQL 和索引的初学者。所以我不太确定如何在查询中使用索引。我猜我上面做的那个是正确的?为什么要花这么多时间?我该如何改进它?我希望我对每个 company_idx 的查询尽可能快。

当我运行 EXPLAIN 时,我得到:

[{'Cardinality': 115751,
  'Collation': 'A',
  'Column_name': 'company_idx',
  'Comment': '',
  'Index_comment': '',
  'Index_type': 'BTREE',
  'Key_name': 'idx_time',
  'Non_unique': 1,
  'Null': 'YES',
  'Packed': None,
  'Seq_in_index': 1,
  'Sub_part': None,
  'Table': 'Scores'},
 {'Cardinality': 45831976,
  'Collation': 'A',
  'Column_name': 'timestamp',
  'Comment': '',
  'Index_comment': '',
  'Index_type': 'BTREE',
  'Key_name': 'idx_time',
  'Non_unique': 1,
  'Null': 'YES',
  'Packed': None,
  'Seq_in_index': 2,
  'Sub_part': None,
  'Table': 'Scores'}]

标签: mysqlsqlindexing

解决方案


您的索引对于查询看起来是正确的。您正在强制使用索引,因此如果可能,我们可以假设正在使用索引。

一个问题可能是无法使用索引。如果您对列有类型问题,就会发生这种情况。例如,比较值11是一个数字。如果customer_idx是字符串,则有问题。比较应该是一个字符串 -- '11'

另一个问题很简单,可能有很多数据。即使只有百分之几的行符合条件,索引也无济于事。索引的一个主要用途是“大海捞针”查询。他们帮助找到一个小子集。如果您需要全部或大部分干草堆,它们无济于事。


推荐阅读