2017-01-24 2 views
0

Если я хочу, чтобы найти записи, где данное поле равно некоторое значение, я используюРазница в стоимости между «WHERE A = x» и «WHERE A IN (x)»?

SELECT * from TableName WHERE FieldName=value; 

Если я хочу, чтобы выбрать записи, которые соответствуют списку значений, можно использовать

SELECT * from TableName WHERE FieldName IN (value1, value2, ..., valueN); 

, чтобы избежать WHERE FieldName = value1 OR FieldName = value2 OR... (отредактированный, так как, казалось бы, это заблуждение о цели вопроса)

Использование .eqp on, по-видимому, предполагает, что когда мой список содержит только один элемент, два запроса эквивалентны.

Это правда?

Если да, могу ли я свободно использовать WHERE FieldName IN (...) и проанализировать значения в список с разделителями-запятыми (исключая конечные запятые и т. Д.) Без затрат на запрос?

Казалось бы, это значительно упростит кодирование моих запросов, но я удивлен тем, что у оператора нет дополнительной сложности, независимо от того, что список является только одним элементом.

Редактировать: Чтобы было ясно, я не буду использовать OR в любом случае - если у меня есть одно значение, то ранее я использовал первую форму (FieldName=value). Если у меня было несколько значений, я использовал IN (val1, val2, ...). Основываясь на комментариях, кажется, что я могу удалить код, который мне нужно использовать для их обработки, и вместо этого искать только для IN (value1).

+0

Возможный дубликат [IN vs OR в предложении SQL WHERE] (http://stackoverflow.com/questions/3074713/in-vs-or-in-the-sql-where-clause) –

+0

Информация, указанная в ответах, полезна, но вопрос другой. – chrisb2244

+0

Нет, я не согласен, это тот же вопрос. –

ответ

1

Когда SQLite оценивает, что список IN настолько короток, что его накладные расходы больше, чем на OR-связанных сериях сравнений равенств, он преобразует запрос в последнюю форму. В настоящее время это делается для списков IN размера 1 или 2.

Как показано EXPLAIN, код для одного элемента одинакова:

 
sqlite> explain select * from t where x = 1; 
addr opcode   p1 p2 p3 p4    p5 comment  
---- ------------- ---- ---- ---- ------------- -- ------------- 
0  Init   0  10 0     00 Start at 10 
1  OpenRead  0  2  0  1    00 root=2 iDb=0; t 
2  Rewind   0  8  0     00    
3  Column   0  0  1     00 r[1]=t.x  
4  Ne    2  7  1  (BINARY)  51 if r[1]!=r[2] goto 7 
5  Copy   1  3  0     00 r[3]=r[1]  
6  ResultRow  3  1  0     00 output=r[3] 
7  Next   0  3  0     01    
8  Close   0  0  0     00    
9  Halt   0  0  0     00    
10 Transaction 0  0  1  0    01 usesStmtJournal=0 
11 TableLock  0  2  0  t    00 iDb=0 root=2 write=0 
12 Integer  1  2  0     00 r[2]=1  
13 Goto   0  1  0     00    
sqlite> explain select * from t where x in (1); 
addr opcode   p1 p2 p3 p4    p5 comment  
---- ------------- ---- ---- ---- ------------- -- ------------- 
0  Init   0  10 0     00 Start at 10 
1  OpenRead  0  2  0  1    00 root=2 iDb=0; t 
2  Rewind   0  8  0     00    
3  Column   0  0  1     00 r[1]=t.x  
4  Ne    2  7  1  (BINARY)  51 if r[1]!=r[2] goto 7 
5  Copy   1  3  0     00 r[3]=r[1]  
6  ResultRow  3  1  0     00 output=r[3] 
7  Next   0  3  0     01    
8  Close   0  0  0     00    
9  Halt   0  0  0     00    
10 Transaction 0  0  1  0    01 usesStmtJournal=0 
11 TableLock  0  2  0  t    00 iDb=0 root=2 write=0 
12 Integer  1  2  0     00 r[2]=1  
13 Goto   0  1  0     00    

(SQLite также делает opposite transformation, когда у вас слишком многие термины OR.)

Смежные вопросы