假设我有一个26000字的字典,每个字母的字母有1000个字 如果我想找到所有带有“e”的单词,我写道:
SELECT *
FROM dict
WHERE word LIKE '%e%';
如果我想将其减少到只有以'a'开头的单词,我可以改变类似的条件,或者我可以这样做:
SELECT *
FROM dict
WHERE word LIKE '%e%'
AND id < 1000;
如果从左到右评估条件,那么很多单词会在其中加上字母'e',因此只返回true才会失败第二个要求但如果从右到左评估条件,我会期望更快的结果。< / p>
我的问题是,将id < 1000
作为第一个或第二个条件会更好,还是取决于数据库的类型。
答案 0 :(得分:1)
条件的位置无关紧要,需要相同的扫描次数(如果适用)。它们不按顺序解析 - 优化器根据表统计信息和索引(如果存在)确定应用的内容以及何时应用。这些统计数据会发生变化,并且可能会过时(这就是维护很重要的原因)。
答案 1 :(得分:1)
假设id < 1000
等同于
SELECT * FROM dict WHERE word LIKE'a%'
。
如果您以这种方式设计数据库,则会违反First Normal表单。 1NF,具体来说:行没有自上而下的排序。 从技术上讲,没有办法确保此顺序有效,特别是如果您想在设置初始状态后添加以“A”开头的单词。
答案 2 :(得分:0)
现代关系数据库管理系统的一个关键设计原则是,您(用户)无法真正控制或说明RDBMS如何将数据实际存储在硬盘驱动器上。这意味着您不能假设数据是(a)按字母顺序存储在驱动器上,或者(b)当您检索数据时,它将按字母顺序检索。绝对100%确定你获得所需数据的唯一方法就是拼出你想要的方式,而其他任何事情都是假设有一天你可能会爆炸。
为什么这很重要?因为您的查询假设您将获得的数据将按字母顺序排列,从“A”开始并向上移动。 (并假设一致的情况 - “A”与“a”怎么样?任何带有前导空格或数字的东西?不同的系统以不同的方式处理不同的数据......)修复这个很简单,添加一个ORDER BY
子句,如:
select * from dict where word like ("%e%") and id < 1000 order by word;
当然,如果你有超过1000个单词以“A”开头并且包含“e”,那么你就麻烦了...如果你的数量少于1000,你就会得到一堆“B”话。尝试类似:
select * from dict where left(word. 1) = "A" and word like ("%e%");
根据您的RDBMS和表中的任何索引,系统可以首先识别所有“A”字,然后仅运行“包含 e ”检查。
答案 3 :(得分:0)
尝试切换where子句条件,然后比较执行计划。
这将显示差异,如果有的话(在这种情况下,我猜它们将是相同的)
最重要的是,大部分时间没有区别。 但是它可以改变执行计划。