【问题标题】:SQLITE: How to make indexing work for you?SQLITE:如何让索引为你工作?
【发布时间】:2016-04-11 11:38:56
【问题描述】:

我有一个包含大约一百万个条目的员工的 sqlite 数据库。

company:

emp_id(primary) | first_name | last_name | company_name | job_title

数据库仅包含 10 个不同的公司名称(即假设每个公司有大约 10 万名员工) 我在公司名称上创建了一个索引:

CREATE INDEX cmp_name ON company(company_name)

但我在执行查询时没有获得任何速度:

带索引:

select * from company INDEXED BY cmp_name where company_name = 'XYZ corp';
Time: 88.45 sec

没有索引:

select * from company where company_name = 'XYZ corp';
Time: 89.12 sec

我做错了什么?

【问题讨论】:

  • 您仍在选择 100.000 行,索引不会神奇地使该部分更快。你觉得select count(*) 有什么不同吗?
  • @Thilo 如何修改我的索引以提高速度?
  • 所以你为一个拥有 100 万员工的组织工作,但你被困在使用 sqlite 作为关系数据库?不是 oracle、postgresql 或 sql server?
  • 实际场景不同。我以员工为例。

标签: sql sqlite indexing query-optimization


【解决方案1】:

一个数据库被组织成页面。如果超过十行适合一个页面,那么平均而言,读取所有“XYZ Corp”行仍然需要读取大多数页面。此外,由于索引条目与表格行的顺序不同,表格的页面不再按顺序读取。

加快此查询的唯一方法是使用covering index。首先,将读取的列数减少到您实际需要的绝对最小值,然后将所有这些列添加到公司名称索引(INTEGER PRIMARY KEY 列隐含地包含在每个索引中):

CREATE INDEX cmp_name_and_other_stuff ON company(company_name, last_name);

SELECT emp_id, last_name FROM company WHERE company_name = 'XYZ Corp';

对每个查询都这样做会浪费大量存储空间。

【讨论】:

  • 这是否意味着,如果我想为 5 列创建搜索查询,我应该为所有这 5 列创建一个索引?
  • 没有。减少要读取的表页数的单列索引工作得很好。此外,只有在对所有最左边的列进行查找时,才能使用索引。
  • 但是我不明白你说的一件事:阅读公司名称仍然需要阅读大部分页面。但是如果我根据公司名称索引了数据库,它不应该只读取 1/10 页,即只读取 XYZ 公司索引的(索引)页面吗?
  • 仅当与该公司的行恰好存储在相同的页面中时,即如果表被公司意外排序。
  • 只在索引中包含主键(emp_id)就可以得到一些改进,但是覆盖的索引会更好。
猜你喜欢
  • 2016-02-24
  • 1970-01-01
  • 1970-01-01
  • 2021-03-22
  • 2012-08-19
  • 1970-01-01
  • 2021-04-21
  • 1970-01-01
  • 2011-11-09
相关资源
最近更新 更多