PreparedStatements следует использовать очень осторожно в предложениях WHERE.
Предположим, что таблица определена как:
create table t (int o, k varchar(100), v varchar(100))
(например, "o: идентификатор объекта (внешний ключ), k: ключ-атрибут, v: значение-атрибут").
Кроме того, существует (неуникальный) индекс для v.
create index ixt on t ( v )
Предположим, что эта таблица содержит 200 миллионов строк, вставленных как:
for (i = 0; i < 100*1000*1000; i++) {
insert into t (o,k,v) values (i,'k1','v1');
insert into t (o,k,v) values (i,'k2', Convert(i, varchar));
}
(«Таким образом, каждый объект o имеет атрибуты k1 = v1 и k2 = o»)
Тогда вы не должны строить запросы вроде:
select o,p,v from t as tx, t as ty where tx.o=ty.o and tx.k=? and tx.v=? and ty.k=? and ty.v=?
("найти объекты, которые имеют два заданных атрибута")
Мой опыт работы с ORACLE и MSSQL заключается в том, что для выполнения этих запросов может потребоваться много минут . Это верно, даже если ни одна строка не соответствует предложению where. Это зависит от того, решит ли SQL-сервер сначала поискать tx.v или ty.v.
Один шок вставляет значения для столбцов k и v непосредственно в оператор. Я думаю, это потому, что SQL-серверы учитывают значения при расчете плана выполнения.
Запрос, который выглядит так, всегда возвращается через миллисекунды:
select o,p,v from t as tx, t as ty where tx.o=ty.o and tx.k='k1' and tx.v='v1' and ty.k='k2' and ty.v='1234'
("SQL-сервер всегда будет сначала искать v = '1234', а затем v = 'v1'")
Привет
Wolfgang