简单的问题。想知道长IN子句是否是一种代码味道?我真的不知道如何证明它是正确的。我不知道为什么它闻起来像我想的那样。
select
name,
code,
capital,
population,
flower,
bird
from us_states
where
code in
('NJ', 'NY', 'PA', 'CA', 'AL', 'AK', 'AZ',
'IL', 'IN', 'KY', 'KS', 'DC', 'MD', 'MA')数据库通常如何实现这样的查找?是否创建并连接了临时表?或者它只是扩展成一系列的逻辑Or?
感觉它应该是一个连接...
我并不是说所有的IN子句都不好。有时候你会情不自禁。但在某些情况下(特别是它们变得越长),您要匹配的元素集实际上来自于某个地方。难道不应该加入进来吗?
是否值得创建一个临时表(通过应用程序级别),其中包含您想要搜索的所有元素,然后对其执行真正的连接?
select u.*
from us_states u
join #chosen_states t
on u.code = t.code发布于 2011-06-03 03:42:35
我认为这是一种代码的味道。首先,数据库对SQL子句中允许的元素数量有限制,如果您的IN是动态生成的,那么您最终可能会遇到这些限制。
当列表开始变得冗长时,我会转换为使用带有临时表的存储过程,以避免出现任何错误。
我怀疑性能是一个主要问题,但与NOT IN子句不同,IN子句非常快,因为它们可能会短路。
发布于 2011-06-03 03:44:41
是否值得(通过应用程序级别)创建一个临时表。
IN的问题是它不使用索引,并且源表中的每一行都会重复进行比较(最坏的情况是x14 )。
如果您将索引放在连接字段上,那么创建一个临时表是一个好主意。
这样,查询就可以使用BTree索引直接查找该值,该索引应该只进行3到4次比较最坏情况log2(14) =3.thing
这要快得多。
如果你很聪明,你甚至可以使用hash-index,在这种情况下,数据库只需要做一次比较,与btree索引相比,你的查询速度提高了3倍。
使用临时表的提示
确保使用内存表
使用hash index作为主键。
尝试在一条语句中执行插入操作。
由于使用散列索引的查找时间为O(1),因此创建临时表所花费的半恒定时间将与加速相比相形见绌。
发布于 2011-06-03 03:45:45
确切地说,我不知道这是一种代码气味。有时你只是有一个很长的清单,你的条件可能存在的东西in。
至于创建一个包含元素的临时表(甚至是查找表),并对其进行连接(或者甚至执行where [column] in (select [lookup] from [lookuptable])是我首选的方法之一),有大量的值b)几乎不会改变。
*:“如果且仅当”
https://stackoverflow.com/questions/6219501
复制相似问题