- 1
- 2
- 3
- 4
- 5
- 6
SELECT id FROM (
SELECT a.id, b.idNOT FROM stable a
LEFT JOIN
(SELECT idNOT FROM nottable) b
ON a.id = b.idNOT ) fromtable
WHERE idNOT IS NULL
Нашли или выдавили из себя код, который нельзя назвать нормальным, на который без улыбки не взглянешь? Не торопитесь его удалять или рефакторить, — запостите его на говнокод.ру, посмеёмся вместе!
−170
SELECT id FROM (
SELECT a.id, b.idNOT FROM stable a
LEFT JOIN
(SELECT idNOT FROM nottable) b
ON a.id = b.idNOT ) fromtable
WHERE idNOT IS NULL
SQL Server compact не понимает NOT IN.
Эквивалент будет:
SELECT id FROM stable
WHERE id NOT IN (SELECT idNOT FROM nottable)
Lowezar 10.10.2013 08:19 # +4
Lowezar 10.10.2013 08:23 # 0
Lowezar 10.10.2013 08:31 # +1
SELECT a.id FROM stable a LEFT JOIN nottable b ON (a.id = b.idNOT) WHERE b.idNOT IS NULL;
DBdev 10.10.2013 11:42 # +2
Там еще много чего... урезано.
Почему люди себе так усложняют жизнь? Ведь можно просто:
crastinus 10.10.2013 15:57 # 0
3.14159265 10.10.2013 12:38 # +1
а) not in - стрёмная штука, если можно то стоит избегать её использования. в индекс оно не попадает.
б) подзапросы - плохо
в) left join на некоторых бд быстрее, так что в этом случае может просто не говно, а даже благо - не даёт написать кривой запрос.
Выше DBdev предложил вариант.
Lowezar 10.10.2013 13:12 # 0
Но суть не в том: говном были обе попытки автора. :) Первая попадает под ваше а), а вторая... Ну... Утверждение б) не верно, правильно составленные подзапросы там, где они действительно нужны - хорошо. Но в реализации автора они таки не нужны, у него получился очень достойный этого сайта запрос. :)
crastinus 10.10.2013 16:22 # +1
потому и запостил;)
defecate-plusplus 10.10.2013 19:46 # 0
или это в ms sql не попадает?
DBdev 14.10.2013 11:43 # +1
anonimb84a2f6fd141 10.10.2013 18:49 # 0
WHERE id NOT IN (SELECT idNOT FROM nottable)
Один полуебок в подобном стиле заменил join, а потом оказалось, что во внутреннем запросе десятки тысяч идов и мускул тормозил, а потом падал.
eth0 10.10.2013 19:17 # 0
anonimb84a2f6fd141 10.10.2013 19:33 # 0
>Пока данных было мало,
Причем тут кроссплатформенность-то?
defecate-plusplus 10.10.2013 19:41 # +1
anonimb84a2f6fd141 10.10.2013 19:44 # 0
defecate-plusplus 10.10.2013 19:48 # +2
приведи пример, а мы просто посмотрим explain plan
anonimb84a2f6fd141 10.10.2013 20:31 # 0
WHERE id IN (SELECT id FROM nottable)
Только подзапрос возвращает большое число строк (>10k)
bormand 10.10.2013 20:47 # 0
anonimb84a2f6fd141 10.10.2013 21:13 # −3
bormand 10.10.2013 21:18 # +1
Например, чтобы выбирать поля одновременно из джвух и более таблиц: Ваш кэп.
anonimb84a2f6fd141 11.10.2013 00:32 # 0
bormand 11.10.2013 05:25 # +1
anonimb84a2f6fd141 11.10.2013 21:58 # 0
Lowezar 11.10.2013 22:28 # +1
In most cases JOINs are faster than sub-queries and it is very rare for a sub-query to be faster.
In JOINs RDBMS can create an execution plan that is better for your query and can predict what data should be loaded to be processed and save time, unlike the sub-query where it will run all the queries and load all their data to do the processing.
anonimb84a2f6fd141 11.10.2013 22:39 # 0
Lowezar 12.10.2013 08:35 # 0
Но реально на практике у меня подзапрос работал быстрее только когда надо было "дырки" в последовательностях значений считать: удалённые ID, пропущенные даты... Там просто с джоином слишком много повторяющихся строк получалось. :)
bormand 11.10.2013 23:01 # +1
Не всегда, а только если тебе нахер не сдались поля из второй таблицы.
Подзапросы учили не юзать готовя вас к встрече с СУБД, которые не умеют их толком оптимизировать ;)
А с точки зрения реляционной теории, в таких случаях, если я не ошибаюсь, что in, что exists, что join - все однохуйственно. Главное not in никогда не юзай, у него засада с null'ами и троичной логикой.
anonimb84a2f6fd141 12.10.2013 01:39 # 0
crastinus 12.10.2013 07:03 # 0
Ты ее в вузе проходил?
bormand 12.10.2013 08:25 # 0
Нет конечно. Откуда реляционная теория в нашем Бобруйском Институте?) У нас на предмете, посвященном СУБД, рассказывали о Профессиональной Лисе...
crastinus 13.10.2013 11:24 # +1
А у нас тип приезжал, постоянно причесывал волосы, но про нормальные формы рассказал. Сети вел придурок зав.кафедры, и расказывал о модуляциях.
Но самое веселое было перед дипломом, ни один из наших кандидатов наук радистов не мог припаять ARM (нужна неделя и десяток микросхем, чтобы заполучить этот скилл). Из моих одногрупников только 2 нормальных, и то один из них одинэсник. Еще один типок также может припаивать армы, но дурачок уже не может использовать их возможности по-серьезному, хотя армы подгоняли много исходников для прошивки. Да, воспоминания.
bormand 13.10.2013 11:31 # +1
60 ваттным паяльником с жалом в 5мм? :) Феном на хорошо залуженную плату то они влет садятся ;)
crastinus 13.10.2013 11:36 # +1
А ты где с ними встречался?
bormand 13.10.2013 11:46 # +2
Да игрался для души с ARM и AVR :)
> Тот другой типок делал все это дело утюгом.
Жесть. А остальные детали в это время уплывали со своих мест? :) Самое зверство которое я учинял с электроникой - распайка материнки над печкой, которую топят углём... SMDятина падала и вспыхивала красивыми искорками, а я в перчатках варежках дергал разъемы, полевики, и прочие крупные и полезные вещи... Суровый сибирский демонтаж ;)
LispGovno 13.10.2013 12:13 # 0
Остальное приходилось делать рассыпухой (её легко впаивать из-за малоножья) и впаивать после этой зверской операции.
bormand 13.10.2013 12:22 # +1
Хм. LispGovno == crastinus?
crastinus 13.10.2013 12:24 # +2
Хотя, конечно,LispGovno тоже может быть рыжим, но не моим знакомым.
Stertor 13.10.2013 13:05 # 0
anonimb84a2f6fd141 13.10.2013 21:15 # 0
bormand 13.10.2013 21:29 # 0
А хрен знает :) Полевики живые, микрухи, которые ими управляют - тоже. А остальные чипы проверить было нечем, да и незачем...
bormand 10.10.2013 20:55 # 0
Lowezar 10.10.2013 21:14 # 0
bormand 10.10.2013 21:23 # 0
defecate-plusplus 10.10.2013 21:31 # 0
потому то я и переспросил, что может дело в мс скл
а по твоей ситуации - 1) твои таблицы свежие, может в постгресе тоже, как в оракле, надо сделать analyze table для достоверных тестов?, 2) в таблице особо данных не хранится, вот ты навесь по килобайту данных на строку, чтобы индекс было ещё выгодней юзать
bormand 10.10.2013 21:51 # 0
Навесил по три колонки с char(255), сделал analyze... Планы не поменялись. Не хочет он юзать индексы для разности множеств, и хеширует вторую табличку заново...
Кажется понял в чем причина... В первых двух запросах он индексы использует в merge (как я понимаю тупо бежит по обоим индексам и выбирает общее).
В запросах на разность множеств же ему нужно проверять отсутствие записи во второй таблице для каждой записи из первой. И, видимо, хеш для этого подходит лучше чем b-tree, поэтому он и хеширует айдишки вместо использования индекса. Так что надо увеличить количество записей в nottable, чтобы затраты на построение хеша перевесили...
defecate-plusplus 10.10.2013 22:00 # 0
очевидно, что в подзапросе idnot должен быть fk на первую таблицу (иначе какого черта вообще вычитать две несвязанные друг с другом колонки)
оракл не делает лишнего индекса для колонки fk, вот, видимо и приходится ему только юзать натуральный индекс (pk) от stable
...сейчас уже лень открывать опять удаленный стол на работу, чтобы вставить план запроса от ОП
bormand 10.10.2013 22:11 # +3
bormand 10.10.2013 22:27 # +2
Since PostgreSQL cannot flush a hashed subplan onto the disk, it will estimate the subquery size, and if it decides that it will not fit into work_mem, it will resort to using a mere subplan which will be either executed for each row from t_left, or materialized and the rows will be searched for in a loop.
This can be very bad since the optimizer will just change the plan as t_right will overgrow a certain limit and one day the query will just become very slow without any apparent reason.
Печалька ;)
Вывод: в постгресе not in работает быстро ровно до тех пор, пока хеш входит в память. А просто in, join, exists/not exists и решение от DBdev с left join + not null планируются и исполняются вполне адекватно даже при 3кк различных id в nottable.
bormand 10.10.2013 22:04 # 0
defecate-plusplus 10.10.2013 21:14 # +3
defecate-plusplus 10.10.2013 21:15 # +3
т.е. везде косты получились одинаковые
на самом деле всю эту портянку я привёл лишь в качестве примера того, что в нормальной субд должен быть нормальный оптимизатор - выкидывающий подзапросы, если их можно выкинуть, знающий состав индексов и умеющих их к месту применить и т.д.
mysql - это явно не нормальная субд
defecate-plusplus 10.10.2013 21:23 # +2
Stertor 10.10.2013 22:03 # −3
defecate-plusplus 10.10.2013 22:56 # +1
anonimb84a2f6fd141 11.10.2013 00:32 # −2
defecate-plusplus 11.10.2013 00:36 # +1
у меня тут _таблицы_ по 300гб остались в наследство в субд, не вылезшей из 80х, то ли дело MyISAM
anonimb84a2f6fd141 11.10.2013 01:50 # −3
> копеечные 10к строк в подзапросе
Уже на них стало плохо. И?
bormand 11.10.2013 05:30 # +2
Ну если "субд из 80х" работает быстрее и стабильнее "субд 21го века", и не залипает на жалких 10к строк в подзапросе, то у меня для тебя плохие новости :)
anonimb84a2f6fd141 11.10.2013 22:06 # −2
anonimb84a2f6fd141 13.10.2013 00:40 # +1
Stertor 13.10.2013 01:03 # −3
Lure Of Chaos 13.10.2013 01:05 # 0
Stertor 13.10.2013 01:06 # −1
как комариный укус в анус.
kegdan 13.10.2013 01:19 # 0
Lure Of Chaos 13.10.2013 01:21 # +2
LispGovno 13.10.2013 01:07 # +1
Однокласники?
Stertor 13.10.2013 01:08 # 0
Все, адью, засиделся я с вами. Парсер давно написан. Подрочить и спать. Хотя можно и просто спать, я подумаю.
LispGovno 13.10.2013 01:10 # 0
anonimb84a2f6fd141 13.10.2013 04:31 # +3
Stertor 13.10.2013 09:17 # 0
LispGovno 13.10.2013 12:09 # +2
bormand 11.10.2013 05:28 # 0
bormand 11.10.2013 05:34 # 0
defecate-plusplus 11.10.2013 07:29 # +1
зачем пользоваться консольным клиентом, если есть нормальные инструменты
в частности, все что я поднасрал в топик, я сделал через sql developer
однако, sql developer имеет фичу нагло виснуть при открытии 50+ МБ .sql файлов, но это уже совсем другая история
roman-kashitsyn 11.10.2013 08:10 # 0
anonimb84a2f6fd141 11.10.2013 22:09 # 0
defecate-plusplus 11.10.2013 22:44 # 0
dbms_xplan же
вумудщзук красиво с раскрывающимся меню план выдает, но это непригодно для копипаста в наш уютный
anonimb84a2f6fd141 12.10.2013 01:36 # 0
Что это?
anonimb84a2f6fd141 11.10.2013 22:08 # 0
sql developer нагуглил и пользовался им только ради этого.
LispGovno 10.10.2013 20:00 # 0
anonimb84a2f6fd141 10.10.2013 21:12 # 0
LispGovno 10.10.2013 21:41 # 0
anonimb84a2f6fd141 11.10.2013 01:51 # 0
bormand 11.10.2013 05:29 # +1
anonimb84a2f6fd141 12.10.2013 18:46 # 0
Все-таки интересно, почему эти полуебки выбрали такую сортировку?
eth0 13.10.2013 16:49 # 0
При этом, на DB2 объёмы были вполне промышленными (ну и сервера не бытовые, конечно), а вот для обрушения mysql хватило десятков тысяч записей.
crastinus 11.10.2013 06:54 # 0
Не исправили.
anonimb84a2f6fd141 12.10.2013 01:36 # 0
crastinus 12.10.2013 07:05 # 0
SELECT * FROM tabl WHERE id IN (...)
Превращается в
SELECT * FROM tabl WHERE EXIST(...).
bormand 12.10.2013 08:23 # +1
Что в этом плохого? У нормального оптимизатора что exists, что in одинаково быстры.
crastinus 11.10.2013 07:17 # 0
Исходный запрос был не хай лоад, а примерно такой
SELECT id FROM stable
WHERE id NOT IN
(SELECT idNOT FROM nottable1
UNION
SELECT idNOT FROM nottable2
.....)
Юнион удалил бы повторяющиеся индексы, и никаких бы проблем не было (даже десятка индексов не выбрал бы).
Нагруженные системы это другое дело. Да и какая нагрузка будет в MS-эквиваленте sqlite?
guest 11.10.2013 14:15 # −12