鉴于我在本地Sqlite数据库中有一个大表(大约5'000'000行),这样的模式
id
(整数,唯一),例如6543
description
(文字),例如"any meaningful text"
tags
(文字),例如"(living)(home)(garden)"
因此,如果我需要计算标记为'home'和'garden'的所有条目,我会
SELECT count(id)
FROM tbl
WHERE tags LIKE ‘%(home)%'
AND tags LIKE '%(garden)%'
显然,这需要永远。 (我用2'000'000条目表测试了它,花了93秒......)
引入新列是否明智,每个标记一个(最多五个)?
所以我有像
这样的列 id | description | tag1 | tag2 | tag3 | tag4 | tag5
34 | blahblah | home |garden| null | null | null
相应的查询看起来像
SELECT count(id)
FROM tbl
WHERE (tag1 = 'home' OR tag2 = 'home' OR tag3 = 'home' OR tag4 = 'home' OR tag5 = 'home')
AND (tag1 = 'garden' OR tag2 = 'garden' OR tag3 = 'garden' OR tag4 = 'garden' OR tag5 = 'garden')
这实际上更好吗?
我只是不知道什么是最好的。我确信有一种方法可以减少查询时间...但我不知道。
非常感谢任何帮助!
或者,也许,您有一个全新的想法,如何重组数据和/或查询,使其更快。
提前致谢!
答案 0 :(得分:0)
当您使用条件...<field> LIKE '%<sub-str>%'
时,您正在触发全表扫描,因此需要很长时间。尽管如此,对于带有字符串(字段tags
),例如64个字符的2M记录,在我看来,93秒的时间太长了。我怀疑这个问题不是来自全面扫描。
我建议您检查以下查询所需的时间:
select count(*)
from <tablename>
where tags like '(home)%' ;
对于2M行,这不应超过几秒钟。如果是这样,我会在其他地方搜索性能问题。
此外,您可以存储|living|home|garder|...
之类的代码并搜索tags like '%|home|%'
[这不会解决您的问题,但由于您要用{{替换)(
,因此节省了一些空间1}}]。
编辑:
我刚刚意识到你正在使用两个条件(WHERE ... AND)。请尝试以下方法:
|
答案 1 :(得分:0)
如果您有多个相同的实例,则应将其放入多行。 在这种情况下,这将导致标签的单独表格:
CREATE TABLE tags (
id INTEGER REFERENCES tbl(id),
tag TEXT
);
CREATE INDEX tags_index ON tags(tag);
然后,您可以使用tag
列上的简单查找执行查询,这些查询因索引而有效:
SELECT count(*)
FROM tbl
WHERE id IN (SELECT id FROM tags WHERE tag = 'home')
AND id IN (SELECT id FROM tags WHERE tag = 'garden');
或者,使用compound query:
SELECT count(*)
FROM (SELECT id FROM tags WHERE tag = 'home'
INTERSECT
SELECT id FROM tags WHERE tag = 'garden');