以下哪个查询会更快,更优化(以及为什么):
SELECT * FROM items WHERE w = 320 AND h = 200
(w和h为INT)
SELECT * FROM items WHERE dimensions = '320x200'
(维度为VARCHAR)
答案 0 :(得分:5)
以下是一些实际测量。 (使用SQLite;稍后可以尝试使用MySQL。)
数据= w,h∈{1 ... 1000}的所有1,000,000个组合,按随机顺序排列。
CREATE TABLE items (id INTEGER PRIMARY KEY, w INTEGER, h INTEGER)
执行SELECT * FROM items WHERE w = 320 and h = 200
的平均时间(20次运行)为5.39±0.29μs。
CREATE TABLE items (id INTEGER PRIMARY KEY, dimensions TEXT)
平均执行时间SELECT * FROM items WHERE dimensions = '320x200'
为5.69±0.23μs。
效率方面没有显着差异。
可用性方面存在巨大差异。例如,如果要计算矩形的面积和周长,则可以轻松实现双列方法:
SELECT w * h, 2 * (w + h) FROM items
尝试以其他方式编写相应的查询。
答案 1 :(得分:2)
可能知道这一点的唯一方法就是运行它。我怀疑如果使用的所有列都被索引,那么基本上没有区别。如果INT是4个字节,它将与字符串几乎相同。
一个皱纹就在于如何存储VARCHAR。如果你使用常量字符串大小,它可能比VARCHAR快,但主要是因为你的select *
需要得到它。
使用INT的巨大优势是您可以进行更复杂的过滤。仅此一点应该是偏好它的理由。如果您需要范围或宽度,或者您希望在过滤中对宽度进行数学计算,该怎么办?基于列或聚合的约束怎么办?
此外,当您将值添加到编程语言中时,在使用它们之前不需要解析它们(这需要时间)。
编辑:其他一些答案提到了字符串比较。如果已建立索引,则不会进行很多字符串比较。并且可以实现非常快速的比较算法,这些算法不需要逐字节循环。你必须知道mysql确实知道的细节。
答案 2 :(得分:2)
直观地说,如果你不在这些列上创建INDEX
,整数比较似乎更快。
在整数比较中,直接比较32位值与逻辑运算符的相等性。
另一方面,字符串是字符数组,很难比较它们。字符逐字符。
然而,另一点是,在第二个查询中,您有1个要比较的字段,在第一个查询中您有2个字段。如果您有1,000,000条记录且列上没有索引,这意味着您可能在最坏的情况下进行1,000,000次字符串比较(不幸的是,最后的结果是您正在寻找或根本找不到的东西)
另一方面,你有1,000,000条记录,所有记录都是w=320
,那么你也会将它们与h
进行比较。这意味着2,000,000次比较。但是,您在这些字段上创建INDEX,它们将几乎完全相同,因为VARCHAR将被散列(需要O(1)
恒定时间)并将使用INT比较进行比较并花费O(logn)
时间。
结论,这取决于。首选索引可搜索列并使用整数。
答案 3 :(得分:1)
第二个查询,因为匹配精确字符串的机会较小(这意味着较小的记录集但具有更高的基数)
第一个查询,匹配第一列的机会更高,更多行可能匹配(基数较小)
当然,假设为两个场景都定义了索引
答案 4 :(得分:0)
第一个因为比较数字数据更快。
答案 5 :(得分:0)
这取决于数据和可用索引。但是VARCHAR版本很可能更快,因为搜索单个索引可能比两个更快。如果值的组合提供唯一(或“大多数”唯一)结果,而每个单独的H / W值具有多个条目,则它可以使用单个索引将向下缩小到更小的集合。
另一方面,如果在整数列上有多列索引,那么这可能是最有效的。