Добро пожаловать в форум, Guest >> Войти | Регистрация | Поиск | Правила | | В избранное | Подписаться | ||
Все форумы / Microsoft SQL Server |
![]() ![]() |
Топик располагается на нескольких страницах: [1] 2 вперед Ctrl→ все |
Felas Member Откуда: Санкт-Петербург Сообщений: 16 |
Доброго времени суток. Есть таблица содержит примерно 16кк записей, есть задача время от времени выдергивать из нее случайные записи по определенным критериям (WHERE с 4 условиями). Использовать order by newid()религия не позволяет в силу того, что запрос отрабатывает крайне долго. ЗЫ Если нужны еще какие данные все напишу )) Заранее спасибо. |
30 май 13, 16:19 [14371299] Ответить | Цитировать Сообщить модератору |
Паганель Member Откуда: Винница Сообщений: 22551 |
а после наложения Where сколько остается? |
||
30 май 13, 16:23 [14371333] Ответить | Цитировать Сообщить модератору |
Felas Member Откуда: Санкт-Петербург Сообщений: 16 |
Да миллионов. Запрос в чистом виде выглядит примерно так: select top 1 * from table where param1 = X and param2 = Y and param3 = 'Z' and param4 in (1,2,3,4...n). Задача сделать так чтобы полученное значение всегда было случайным. |
||||
30 май 13, 16:28 [14371371] Ответить | Цитировать Сообщить модератору |
Glory Member Откуда: Сообщений: 104760 |
Сколько записей то отбирается фильтром ? |
||
30 май 13, 16:29 [14371387] Ответить | Цитировать Сообщить модератору |
iap Member Откуда: Москва Сообщений: 47047 |
Felas, и сколько же случайных записей надо выдернуть время от времени? |
30 май 13, 16:31 [14371398] Ответить | Цитировать Сообщить модератору |
Felas Member Откуда: Санкт-Петербург Сообщений: 16 |
Если не указывать топ 1 то значение всегда разное от 0 до 10000000 |
||||
30 май 13, 16:31 [14371403] Ответить | Цитировать Сообщить модератору |
Felas Member Откуда: Санкт-Петербург Сообщений: 16 |
Всего 1, но именно случайную, чтобы если запрос выполнялся 2 раза подряд с одними и тем же входными параметрами он возвращал разные записи |
||
30 май 13, 16:32 [14371408] Ответить | Цитировать Сообщить модератору |
iap Member Откуда: Москва Сообщений: 47047 |
Надо сгенерировать случайное id и выбрать из таблицы запись с этим id (или из случайно вычисленного диапазона). Потому что зачем же для каждой записи вызывать NEWID(), если понадобится только одна? |
30 май 13, 16:35 [14371429] Ответить | Цитировать Сообщить модератору |
Паганель Member Откуда: Винница Сообщений: 22551 |
а перечисленные param4 обязательно будут в БД? (мало ли, может они перед этим получены другим select-ом) если так, то не убрать ли из запроса все кроме одного случайного из них |
||||
30 май 13, 16:40 [14371459] Ответить | Цитировать Сообщить модератору |
Felas Member Откуда: Санкт-Петербург Сообщений: 16 |
Все параметры обязательно будут в БД, записей с такими параметрами может быть много очень много, нужна всего 1 и случайная, потому что скрипт запускается примерно 80-100 раз подряд (ну вот такая архитектура приложения (( ) и каждый раз должно быть новое значение, хотя входящие параметры одинаковы |
||||
30 май 13, 16:49 [14371507] Ответить | Цитировать Сообщить модератору |
Felas Member Откуда: Санкт-Петербург Сообщений: 16 |
Можно подробнее, хотя бы примерный запрос ) |
||
30 май 13, 16:49 [14371510] Ответить | Цитировать Сообщить модератору |
ambarka_max Member Откуда: Россия Сообщений: 517 |
Запрос к таблице формируется через хранимую процедуру или прямо из приложения голый запрос посылается? |
30 май 13, 16:55 [14371544] Ответить | Цитировать Сообщить модератору |
Felas Member Откуда: Санкт-Петербург Сообщений: 16 |
Пока никак не формируется, потому что собственно запроса то нет еще, реализовать можно и то и то, главное сам запрос сделать ) |
||
30 май 13, 16:57 [14371557] Ответить | Цитировать Сообщить модератору |
Glory Member Откуда: Сообщений: 104760 |
Т.е. вы хотите из 10 миллионной выборки каждый раз выбирать одну действительно случайную запись ? |
||
30 май 13, 16:59 [14371569] Ответить | Цитировать Сообщить модератору |
Felas Member Откуда: Санкт-Петербург Сообщений: 16 |
Да |
||||
30 май 13, 17:00 [14371574] Ответить | Цитировать Сообщить модератору |
ambarka_max Member Откуда: Россия Сообщений: 517 |
Тогда делаете процедуру. По 4-ем параметрам отбираете ID-шники (например во времянку) и order by newid() возвращаете сразу TOP 80 (сразу все что нужны) Не? |
||||
30 май 13, 17:00 [14371575] Ответить | Цитировать Сообщить модератору |
Felas Member Откуда: Санкт-Петербург Сообщений: 16 |
Делать временную думал, но решил спросить может есть какой другой интересный способ. К сожалению архитектура приложения такова, что она не хранит данные полученные от первого запроса, приложение их обрабатывает и сжигает (понимаю, что не самое лучшее решение, но сделать ничего нельзя с этим). Поэтому запросы запускаются один за одним нужное количество раз. |
||||
30 май 13, 17:04 [14371588] Ответить | Цитировать Сообщить модератору |
ambarka_max Member Откуда: Россия Сообщений: 517 |
Если не подходит, то можно еще реализовать очередь заранее случайных идешников для каждой комбинации отбора. Но тут будет конкуренция поэтому придется повышать уровень в момент чтения очереди. |
30 май 13, 17:04 [14371591] Ответить | Цитировать Сообщить модератору |
Гость333 Member Откуда: Сообщений: 3683 |
Действию "сжигает" соответствует какая-то SQL-команда? |
||
30 май 13, 17:11 [14371635] Ответить | Цитировать Сообщить модератору |
Felas Member Откуда: Санкт-Петербург Сообщений: 16 |
"Сжигает" их внутри себя, причем тут sql-команда? |
||||
30 май 13, 17:13 [14371644] Ответить | Цитировать Сообщить модератору |
iap Member Откуда: Москва Сообщений: 47047 |
Можно же сгенерировать случайный порядковый номер в порядке возрастания ID от 1 до COUNT(*)? После этого выбрать эту запись, используя ROW_NUMBER(), например? Если ID последовательно возрастает без пропусков, то вообще всё идеально будет и без ROW_NUMBER(). |
30 май 13, 17:19 [14371684] Ответить | Цитировать Сообщить модератору |
Гость333 Member Откуда: Сообщений: 3683 |
А обрабатывает как? Я это к чему — если "случайной записью" при двух последовательных запусках запроса окажется одна и та же запись, как поведёт себя приложение? |
||||
30 май 13, 17:21 [14371701] Ответить | Цитировать Сообщить модератору |
Glory Member Откуда: Сообщений: 104760 |
По-моему надо думать над ограничением размера выборки. Например, выбирать не больше 100 записей. Из которых потом уже возвращать одну случайную. |
||
30 май 13, 17:22 [14371708] Ответить | Цитировать Сообщить модератору |
ambarka_max Member Откуда: Россия Сообщений: 517 |
Может быть не понятно выразился: Cоздаете доп таблицу ИдентификаторыОтбора где хранится идентификатор отбора (можно хотя бы в виде текста хранить выражение WHERE). 1.Для каждого уникального WHERE отбираем К записей и помещаем их в таблицу ОчередьНеИспользованных (ИдентификаторОтбора, Использовано NOT NULL, ссылка на ID). Тут можно подумать над сортировкой перед вставкой, дабы выбрать "случайные" K записей 2.Далее основной алгоритм работает так: по выражению WHERE определяем идентификатор отбора и смотрим скока там в ОчередиНеИспользованных. Если что-то есть, читаем, при чтении TOP 1 ... WHERE ИдентификаторОтбора = X AND Использовано = 0 повышаем блокировку до например XLOCK и тут же UPDATE Использовано = 1. Если в очереди нет ничего для нашего WHERE - идем на шаг 1. 3.Возвращаем полученный идешник |
30 май 13, 17:22 [14371709] Ответить | Цитировать Сообщить модератору |
Felas Member Откуда: Санкт-Петербург Сообщений: 16 |
Можно хотя бы примерный скрипт, не являюсь гуру SQL |
||
30 май 13, 17:23 [14371717] Ответить | Цитировать Сообщить модератору |
Топик располагается на нескольких страницах: [1] 2 вперед Ctrl→ все |
Все форумы / Microsoft SQL Server | ![]() |