ty.*_*ty. 1 sql database sqlite
我正在开展一个专注于分析数据库中文本的个人项目.我的目的是做一些有趣的事情并了解SQL和sqlite.因此,考虑到我的新手能力,我希望得到更有效的建议.
比方说,我想在文章中挑选出各种食物A.我分析我的文章,如果我找到了食物F,那么我添加F到表项.然后,添加A.id并F.id给结果.当我分析我的文章,并找到食物G中已经存在的项目,我要做的就是增加A.id和G.id对结果.
所以我的模式如下所示:
id, articleid, item_id, article_idid, foodtype, food如果我想找到所有谈论的文章oranges和grapes任何vegetable,然后我会像这样的东西开始:
SELECT *
FROM articles
INNER JOIN results ON articles.id = results.article_id
INNER JOIN items ON results.item_id = items.id
Run Code Online (Sandbox Code Playgroud)
并添加:
WHERE foodtype='vegetable' OR food='orange' OR food='grape'
Run Code Online (Sandbox Code Playgroud)
实际上,我的数据库要大得多.有成千上万的文章和超过十万个提取的"食物".即使我将事物限制为100个结果,我加入3个表的大多数查询也不会返回.我已经尝试在我的WHERE子句中常见的字段上创建一个索引,比如food和foodtype,但是没有看到任何改进.
我可以对我的数据库或查询进行哪些改进?
查询的第一个问题SELECT *是返回查询中连接的所有表的所有列.这意味着返回评估两侧的JOIN标准中的值.最好写出你需要的实际列,因为你列出的所有三列都有一列 - 这使得正确的值检索变得复杂,除非使用顺序位置(不是一个好的做法 - 改变位置,数据检索不应该是它应该是什么) .id
使用表别名可以最大限度地减少引用特定表所需的内容:
SELECT a.article
FROM ARTICLES a
JOIN RESULTS r ON r.article_id = a.id
JOIN ITEMS i ON i.id = r.item_id
Run Code Online (Sandbox Code Playgroud)
索引外键 - 用于JOIN条件的内容,应该是表的主键后列表中的第二个内容.
然后你必须定期运行ANALYZE命令,因为统计数据是......
...随着数据库内容的变化而不会自动更新.如果数据库的内容发生显着变化,或者数据库模式发生更改,则应考虑重新运行ANALYZE命令以更新统计信息.
这些统计信息是优化程序用于查询决策以及索引存在的统计信息.
您可以尝试重写该查询,以便它不使用带有UNION的OR:
SELECT a.article
FROM ARTICLES a
JOIN RESULTS r ON r.article_id = a.id
JOIN ITEMS i ON i.id = r.item_id
WHERE i.foodtype = 'vegetable'
UNION
SELECT a.article
FROM ARTICLES a
JOIN RESULTS r ON r.article_id = a.id
JOIN ITEMS i ON i.id = r.item_id
WHERE i.food IN ('orange', 'grape')
Run Code Online (Sandbox Code Playgroud)
请注意,这UNION比较慢UNION ALL,因为UNION删除了重复项. UNION ALL更快,因为它不会删除重复项.