Текущий архив: 2006.04.02;
Скачать: CL | DM;
ВнизSELECT ID FROM <SomeTable> WHERE ID IN (3, 7, 5, ...) Найти похожие ветки
← →
TheEd (2006-02-05 05:31) [0]Господа мастера, вопрос вроде банальный, но как заставить данный select сработать так, что бы полученный DataSet содержал записи именно в указанном порядке?
Подробности: БД - IB7.0, ID - ключевое поле, есть задача выбрать записи с ID = x1, x2, x3, ... xN в случайном порядке.
Прикол в том что иногда запрос срабатывает именно так как надо, а иногда "заботливо" сортирует записи по ID так как они в базе лежат! :(
Заранее благодарен!
← →
atruhin © (2006-02-05 07:13) [1]Ты запрос формируешь динамически?
тогда формируй через UNION
select ... from .... where ID = 3
union
select ... from .... where ID = 7
union
select ... from .... where ID = 5
← →
sniknik © (2006-02-05 09:14) [2]union тоже будет сортировать, ему так "удобнее" выбирать дубликаты записей. попробовать union all, он не должен (не знаю как в IB)
вообще гарантию на порядок записей дает только ORDER BY, его я бы и использовал... в MSSQL (временная таблица с автоинкрементом и полем для внесения ID, порядок внесения будет последователен по автоинкременту... после простой JOIN на нее нужной таблице и ORDER BY по автоинкременту. писанины больше но работало бы быстрее на длинных последовательностях)
а вот с IB не знаю как.
← →
atruhin © (2006-02-05 12:07) [3]Да точно. [2] sniknik © (05.02.06 09:14) - прав.
С union all все работает, только что проверил.
← →
Polevi © (2006-02-05 12:08) [4]>sniknik © (05.02.06 09:14) [2]
какая временная таблица, какой инкремент.. зачем
select *, 1 as sortorder from .. where ..
union all
select *, 2 as sortorder from .. where ..
union all
select *, 3 as sortorder from .. where ..
order by sortorder
← →
sniknik © (2006-02-05 12:41) [5]Polevi © (05.02.06 12:08) [4]
> какая временная таблица, какой инкремент.. зачем
sniknik © (05.02.06 09:14) [2]
> писанины больше но работало бы быстрее на длинных последовательностях
http://www.sql.ru/articles/mssql/03060701ArraysAndListsInSQLServer.shtml#overview
Использование вспомогательной таблицы vs Фокус с использованием UNION.
← →
Polevi © (2006-02-05 12:54) [6]причем тут это, автор задал вопрос про сортировку
← →
sniknik © (2006-02-05 13:05) [7]ну так методы решения те же самые, и проблемы втретятся похожие... вот представь, что в последовательности "ID = x1, x2, x3, ... xN" N = к примеру 5 или хуже 50 тыс... и ??? с union не то что медленно, вообще работать не сможет (и без разници где запрос формировать, на сервере или клиенте. на клиенте даже хуже), с временной таблицей будет, и даже не особо напрягаясь.
← →
Polevi © (2006-02-05 15:46) [8]>sniknik © (05.02.06 13:05) [7]
ну раз тебе так хочется при 50 тыс лучше уж OpenXml использовать, по другому ты все равно столько идентификаторов не передашь за раз
← →
sniknik © (2006-02-05 15:58) [9]Polevi © (05.02.06 15:46) [8]
нет, Xml я не буду использовать, однозначно, он медленнее чем с таблицей. а метод с таблицей кстати вовсе не обязывает все идентификаторы за раз передавать... (зачем бездумно следовать написаному? там всего лиш примеры)
выдержка из статьи, раздел "Фокус с Union" .... т.к. при тестировании производительности этот метод оказался значительно медленнее метода сOPENXML
, который в свою очередь медленнееметода итераций
иметода со вспомогательной таблицей
.
← →
atruhin © (2006-02-05 16:02) [10]>>лучше уж OpenXml использовать
а при чем OpenXML и Firebird?
← →
TheEd (2006-02-05 21:34) [11]to sniknik
Спасибо, помогло!
← →
TheEd (2006-02-05 21:42) [12]определённо с временной таблицей красивее: union, если записей много будет очень тяжёл (см. sniknik © (05.02.06 13:05) [7] - он прав!)
← →
Виталий Панасенко (2006-02-06 10:45) [13]http://polesoft.da.ru - UDF (InitRandom/GetRandom)
select field1, field2,...,fieldN, getrandom(1000) fieldN+1 from table
order by fieldN+1
← →
Polevi © (2006-02-06 15:23) [14]xml универсален, кто знает тот поймет
кому нраится всюду CREATE #T втыкать - вперед, труба зовет
← →
Polevi © (2006-02-06 15:24) [15]гы, прям стих получился :-)
← →
evvcom © (2006-02-07 10:50) [16]с union слишком много можем сканов таблицы получить, с помощью индексов можно снизить, но физические чтения блоков все равно могут получиться больше, чем в других вариантах реализации. Может для IB это и не так, я сужу по Ораклу.
Есть еще вариант с одним сканом и без временной таблицы (опять же оракловый), хотя в IB, думаю, case тоже должен быть:
select *
from (
select
*,
case ID
when 3 then 1
when 7 then 2
when 5 then 3
...
else null
end as sortorder
from ...
)
where sortorder is not null
order by sortorder;
← →
atruhin © (2006-02-07 11:09) [17]>>evvcom © (07.02.06 10:50) [16]
Во первых: данный способ подразумевает полный скан таблицы. Все предыдущие методы используют индексы, поэтому будут быстрее.
Во вторых: в IB вроде нет вложенных запросов (версию 7 незнаю), так что наверное не пройдет.
Остается временная таблица, и Union all
← →
sniknik © (2006-02-07 11:38) [18]это можно переделать, взяв только идею
примерно на так (в принципе в FireBird должно работать, CASE там есть, мож синтаксис только поправить придется, а может и нет)
select
case ID
when 3 then 1
when 7 then 2
when 5 then 3
...
end as sortorder
,*
from ...
where ID IN (3,7,5,...)
order by 1
но все одно, ИМХО, это не подойдет для более менее большой последовательности, хотя должно быть уже лучше чем с union (теоретически, практикой не проверено)
← →
evvcom © (2006-02-07 11:48) [19]
> Во первых: данный способ подразумевает полный скан таблицы.
> Все предыдущие методы используют индексы, поэтому будут
> быстрее.
Не так категорично! Не всегда индексы оказываются быстрее фулскана. Если ты выбираешь более 10% записей (вроде такой порог) и не все нужные данные уже сидят в индексе, то оракловый оптимизатор никогда не выберет скан по индексу, т.к. потеря времени на физические чтения очень вероятно, окажется значительно больше потери при фулскане. Возможно, IB этого не учитывает или у него что-то построено в этом смысле не так как у оракла, но тем не менее такое категоричное заявление в этом случае, имхо, не уместно. Ну а переделав как в [18] можно и по индексу пройтись. А оракловый оптимизатор, возможно, и [16] по индексу разрулит. Надо пробовать.
Страницы: 1 вся ветка
Текущий архив: 2006.04.02;
Скачать: CL | DM;
Память: 0.49 MB
Время: 0.041 c