【发布时间】:2016-10-14 14:14:17
【问题描述】:
鉴于我的本地 Sqlite 数据库中有一个大表(大约 5'000'000 行),其架构如下
id(整数,唯一),例如6543
description(文本),例如"any meaningful text"
tags(文本),例如"(living)(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')
这真的更好吗?
我只是不知道什么是最好的。我确定有办法减少查询时间……但我不知道。
任何帮助将不胜感激!
或者,也许,您有一个全新的想法,如何重组数据和/或查询以使其更快。
提前致谢!
【问题讨论】:
-
在我看来,您正在建模标签和 tbl 之间的 M-N 关系。您可以将这些标签放在一个表格中:
CREATE TABLE tbl_tags (tbl_id INTEGER REFERENCES tbl(id), tag TEXT)。或者,如果有一组固定的标签,将它们放在一个表标签中并从 tbl_tags 中引用它。您的第二种方法,使用五个“标签”字段,应该比您的第一种方法快得多。如果 SQLite 找到匹配的标签,它将不会继续评估。你确定你的应用不会有超过 5 个标签吗? -
如果你为你的标签创建一个表,你可以加入那些:
SELECT count(id) FROM tbl INNER JOIN tbl_tags ON tags.tbl_id = tbl.id AND (tags.tag = 'home' OR ...)
标签: sql performance sqlite