Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2006.04.02;
Скачать: [xml.tar.bz2];

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.039 c
3-1139481919
yk
2006-02-09 13:45
2006.04.02
Украшение dbGrid


2-1142934011
Nsk3D
2006-03-21 12:40
2006.04.02
Изменение шрифта


2-1142514252
zorik
2006-03-16 16:04
2006.04.02
Какую СУБД выбрать?


11-1123414583
EVILDeath
2005-08-07 15:36
2006.04.02
Опять proxies =(


4-1137499500
polinom
2006-01-17 15:05
2006.04.02
Memory, как определить размер и область памяти для нового процеса





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский