SQLite3如何使用索引?

问题描述 投票:9回答:2

我正在研究SQLite3的索引。

这里有一张表 COMAPNY。

CREATE TABLE COMPANY(
ID INT PRIMARY KEY     NOT NULL,
NAME           TEXT    NOT NULL,
AGE            INT     NOT NULL,
ADDRESS        CHAR(50),
SALARY         REAL
);

INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (1, 'Paul', 32, 'California', 20000.00 );

INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) 
VALUES (2, 'Allen', 25, 'Texas', 15000.00 );

INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (3, 'Teddy', 23, 'Norway', 20000.00 );

INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (4, 'Mark', 25, 'Rich-Mond ', 65000.00 );

INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (5, 'David', 27, 'Texas', 85000.00 );

INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (6, 'Kim', 22, 'South-Hall', 45000.00 );

INSERT INTO COMPANY VALUES (7, 'James', 24, 'Houston', 10000.00 );

SELECT * FROM COMPANY;

结果。

1|Paul|32|California|20000.0
2|Allen|25|Texas|15000.0
3|Teddy|23|Norway|20000.0
4|Mark|25|Rich-Mond |65000.0
5|David|27|Texas|85000.0
6|Kim|22|South-Hall|45000.0
7|James|24|Houston|10000.0

我们建立一个索引 salary_index,

CREATE INDEX IF NOT EXISTS salary_index on COMPANY (SALARY);

它有什么作用,怎么用?

这次我把旧的索引丢掉后,做了一个这样的索引。

CREATE INDEX IF NOT EXISTS salary_index on COMPANY (SALARY) 
WHERE SALARY > 50000;

在我添加指数后,我做了:

SELECT * FROM COMPANY;

我以为我只看到工资高于50000的人 但我看到了比这更低的人。

我也试着这样做了。

SELECT * FROM COMPANY INDEXED BY salary_index;

然后我得到Error: no query solution显然我必须这样做:SELECT * FROM COMPANY INDEXED BY salary_index WHERE SALARY > 50000;其中条件必须和索引中的一样。

那么......我如何使用索引?

sqlite indexing indices
2个回答
7
投票

索引永远不会改变你的查询的意义,它们能做的是加快你的一些查询,当可能的时候,它们会被自动使用。

索引的作用在于

  • 在索引列上通过比较查找记录。

    SELECT * FROM Company WHERE Salary = 20000.0;
    SELECT * FROM Company WHERE Salary BETWEEN 40000 AND 80000;
    

    这也包括在索引列上的连接;和

  • 对记录进行排序,其中包括GROUP BY和DISTINCT。

    SELECT * FROM Company ORDER BY Salary
    

    其中还包括GROUP BY和DISTINCT。

详情请看文档。查询规划 SQLite查询规划器


3
投票

这是我和我的一位代码高手的对话(Thanks S.P.)。

索引通常是性能的工具.如果你没有一个字段的索引,对该字段的查询将需要对表进行完整的顺序扫描。如果表很小,这不是问题,但是如果你有几万行,或者以上的行,那么全顺序扫描就太慢了。

所以,如果你想得到其中工资< 50000的行,只要在表上创建一个索引,然后发出

SELECT * FROM COMPANY WHERE SALARY < 50000

只要SALARY字段有索引,它就会自动使用正确的索引。

因此,如果我们有两个索引,如

CREATE INDEX salary_index WHERE salary < 50000;
CREATE INDEX age_index WHERE age < 40;

然后我们运行一个查询,如

SELECT * FROM COMPANY WHERE salary < 50000 AND age < 40;

它自动使用上述2个索引进行查询。

在大多数RDBMS中,在一个查询中可以使用一个以上的索引,是的,如果它们适用,就会自动使用。但这可能有限制,而且这些限制是RBDMS特有的。但更好的想法是创建一个包含多个字段的索引。

在一个最佳的情况下,你会在一个单一的索引中包含查询所需的所有字段,所以如果你想要收入超过50 000美元并且年龄小于40岁的雇员,你会定义一个这样的索引。

CREATE INDEX company_salary_age ON company (salary, age);

字段的顺序很重要 这个索引可以用在一个查询中,这个查询有一个关于薪水的WHERE子句,或者薪水和年龄。无薪无龄. 也就是说,索引的任意数量的字段都可以使用,只要它们在索引的前面是相邻的 即。在查询中,你可以省略最后的字段,但不能省略开头或中间的字段。.

© www.soinside.com 2019 - 2024. All rights reserved.