SQLite索引性能

时间:2018-06-12 22:35:47

标签: performance sqlite indexing

我有一个以下布局的表格

email, item_id, json其中

  • email是一个字符串
  • item_id是一个ms的unix时间戳
  • json是与JSON1扩展名一起使用的商品数据

我在该表上还有email, id

的多列索引

我以WHERE email = 'asd' AND item_id > ... AND item_id < ...

的风格执行了大量查询

我已经处理MongoDB多年了,所以我习惯于不处理数据库规范化,只是采用最简单的SQL表格布局。

在手机上,对于35000项目查询,上述样式的查询最多可能需要一秒钟。索引确实被使用了。

通过创建一个包含email, email_id的新表并将原始文件更改为email_id, item_id, json并开始通过JOINS查询来标准化数据库时,我是否会获得明显的性能提升?在这种情况下,email, email_id将包含大约2-5个项目和email_id, item_id, json数千个。

1 个答案:

答案 0 :(得分:1)

使用3测试原始,使用JOIN和其他选项的查询,使用子查询而不是连接来获取基于电子邮件地址的电子邮件ID,并将其与email_id进行比较。子查询名列前茅,最初表现最差。

结果如下: -

SELECT * FROM original WHERE email = 'email3@ouremail.com' AND item_id > 7800 AND item_id < 2404327029516376406
  

行   时间:0.199秒

SELECT * FROM item WHERE email_id = (SELECT email.email_id FROM email WHERE email.email = 'email3@ouremail.com') AND item_id > 7800 AND item_id < 2404327029516376406
  

行   时间:0.082秒

SELECT * FROM item JOIN email ON item.email_id = email.email_id WHERE email.email = 'email3@ouremail.com' AND item_id > 7800 AND item_id < 2404327029516376406
  

行   时间:0.109秒

以下内容用于创建和测试: -

DROP TABLE IF EXISTS original;
CREATE TABLE IF NOT EXISTS original (email TEXT, item_id INTEGER, json BLOB, PRIMARY KEY(email,item_id));
WITH RECURSIVE cnt(x,y,z) 
AS (
    SELECT 'email'||(1 + ABS(random() / (9223372036854775807 / 5)))||'@ouremail.com',
                ABS(random()),
          randomblob(ABS(random() / (9223372036854775807 / 40) ))
            UNION ALL SELECT 
              'email'||(1 + ABS(random() / (9223372036854775807 / 5)))||'@ouremail.com',
                ABS(random()),
                randomblob(ABS(random() / (9223372036854775807 / 40)))  
            FROM cnt LIMIT 350000
)
INSERT INTO original SELECT * FROM cnt;


DROP TABLE IF EXISTS email;
CREATE TABLE IF NOT EXISTS email (email_id INTEGER PRIMARY KEY, email TEXT);
INSERT INTO email SELECT DISTINCT null,email FROM original;


DROP TABLE IF EXISTS item;
CREATE TABLE IF NOT EXISTS item (email_id, item_id, json);
INSERT INTO item SELECT 
    (SELECT email_id FROM email WHERE original.email = email.email),
        item_id,
        json FROM original;


SELECT * FROM original WHERE email = 'email3@ouremail.com' AND item_id > 7800 AND item_id < 2404327029516376406;
SELECT * FROM item WHERE email_id = (SELECT email.email_id FROM email WHERE email.email = 'email3@ouremail.com') AND item_id > 7800 AND item_id < 2404327029516376406; 
SELECT * FROM item JOIN email ON item.email_id = email.email_id WHERE email.email = 'email3@ouremail.com' AND item_id > 7800 AND item_id < 2404327029516376406;

你可能会更糟糕的是运行以下内容并查看输出。

EXPLAIN QUERY PLAN SELECT * FROM original WHERE email = 'email3@ouremail.com' AND item_id > 7800 AND item_id < 2404327029516376406;
EXPLAIN QUERY PLAN SELECT * FROM item WHERE email_id = (SELECT email.email_id FROM email WHERE email.email = 'email3@ouremail.com') AND item_id > 7800 AND item_id < 2404327029516376406;
EXPLAIN QUERY PLAN SELECT * FROM item JOIN email ON item.email_id = email.email_id WHERE email.email = 'email3@ouremail.com' AND item_id > 7800 AND item_id < 2404327029516376406;