Комментарии 41
SELECT * FROM messages WHERE message_id IN (....)
а почему IN а не INNER JOIN?
а почему IN а не INNER JOIN?
-4
Вы, вероятно, подумали, что мы предлагаем вложенный запрос. Ни в коем случае! Подразумевается IN (1,2,3,4...). Вложенные запросы в MySQL даже не рассматриваем.
+4
вельми странно. AFAIK IN (123) преобразуется в OR
0
Ничего странного. Вложенный запрос приводит к вызову вложенного запроса для каждой строки внешнего. А не вычисляется один раз перед выполнением внешнего.
+6
Это истинно только для correlated subqueries. Нормальный оптимизатор СУБД не коррелированные запросы выполняет единожды (не уверен, как с этим в последних версиях mysql)
0
A correlated subquery is a subquery that contains a reference to a table that also appears in the outer query.dev.mysql.com/doc/refman/5.5/en/correlated-subqueries.html
Так что для данного случая дело будет обстоять именно таким образом.
0
Эм, и какие у вас будут references к the outer query?
Внутренний запрос вообще никак от внешнего не зависит, и именно этим вы и пользуетесь, разделяя задачу на 2 запроса
Внутренний запрос вообще никак от внешнего не зависит, и именно этим вы и пользуетесь, разделяя задачу на 2 запроса
0
MySQL смотрит referrence к таблице, а не к значению. Таким образом вложенный запрос вида
select * from messages where messageid in (select messageid from messages where user1=....limit)
не будет оптимизирован как надо.0
Эм, вы уверены? Если это так — то ппц :-S
0
Вы заставили меня сомневаться. Решил проверить и вот, что я получил
Сижу думаю как можно проверить.
There is an error in select query This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
Сижу думаю как можно проверить.
0
Первый же пример по вашей ссылке делает акцент именно на полях, а не таблицах
0
Скорее нужно ссылаться на dev.mysql.com/doc/refman/5.5/en/subquery-restrictions.html
Который объясняет, что mysql сам переписывать не коррелированные запросы — в коррелированные. Т.е. проблема, что вы описали, существует («не будет оптимизирован как надо.»), но причины у неё — иные (запрос хороший, а оптимизатор тупит)
Который объясняет, что mysql сам переписывать не коррелированные запросы — в коррелированные. Т.е. проблема, что вы описали, существует («не будет оптимизирован как надо.»), но причины у неё — иные (запрос хороший, а оптимизатор тупит)
0
Большое спасибо за ссылку. Как-то раньше не попадалась эта страница мне на глаза.
0
Я на неё пришёл из бага bugs.mysql.com/bug.php?id=9090. А в баг — с вашей страницы ))
Честно говоря, тоже впервые её вижу :-)
Честно говоря, тоже впервые её вижу :-)
0
в этом плане оптимизатор у mssql 2008 рулит
0
Вложенные запросы тожно нужно уметь делать:
select * from messages m inner join (select messageid from messages where user1=1 and user2=2 limit) m2 on m.messageid = m2.messageid
select * from messages m inner join (select messageid from messages where user1=1 and user2=2 limit) m2 on m.messageid = m2.messageid
+3
И OR в этом случае отлично оптимизируется всё равно
0
>> Пользователей в нашей системе всего 10, таким образом, у каждой пары собеседников будет в среднем по миллиону сообщений.
А разве среди 10 собеседников не 45 уникальных пар?
А разве среди 10 собеседников не 45 уникальных пар?
0
Во первых, история — сущность личная для каждого пользователя и он может её удалять её на своё усмотрение. Так что получаем как минимум 90.
Во вторых пользователь может писать сам себе. (Оставшиеся 10)
А в третьих я упоминал, что это — иллюстрация проблемы, а не реальная структура. Скрипт просто наполняет таблицу случайными данными. Получается 100 пар.
Во вторых пользователь может писать сам себе. (Оставшиеся 10)
А в третьих я упоминал, что это — иллюстрация проблемы, а не реальная структура. Скрипт просто наполняет таблицу случайными данными. Получается 100 пар.
+3
Но сообщений друг другу они могут понаписать миллионы при должном старании)
0
Если у вас во втором случае 30 млню апдейтов работают так долго, может вам проще вообще пересоздавать таблицу со статистикой с нуля, чем обновлять большое число записей в существующей?
0
Расскажите, пожалуйста, а как вы организовали сортировку 30 миллионов значений? Спасибо.
0
ts является leftmost в ключе key(f1, f2, ts) и запросе типа
WHERE f1=const AND f2=const ORDER BY ts
Так что mysql отлично берёт и сортирует выборку, используя индекс
WHERE f1=const AND f2=const ORDER BY ts
Так что mysql отлично берёт и сортирует выборку, используя индекс
0
Основная идея такая — разбить на примерно одинаковые части. Отсортировать каждую из них в памяти (в несколько потоков). А затем осуществить слияние данных.
Это можно реализовать множеством способов. В данном случае мы воспользовались тем, что значения ключа сортировки равномерно распределены по множеству возможных значений. Потому мы разделили множество возможных значений на 400 диапазонов. Разбили данные на 400 одинаковых частей. Получили 400 файлов с данными. Затем поочерёдно перебираем эти файлы, сортируем в памяти и вставляем данные в таблицу.
Это можно реализовать множеством способов. В данном случае мы воспользовались тем, что значения ключа сортировки равномерно распределены по множеству возможных значений. Потому мы разделили множество возможных значений на 400 диапазонов. Разбили данные на 400 одинаковых частей. Получили 400 файлов с данными. Затем поочерёдно перебираем эти файлы, сортируем в памяти и вставляем данные в таблицу.
+3
Так вы потом эти 400 файлов сливаете? Или у вас 400 независимо отсортированных файлов?
0
Давайте на примере
Диапазон значений 1-10000.
Разбиваю на 10 диапазонов 1-1000, 1001-2000,...,9001-10000.
Беру исходные данные и раскладываю по 10 файлам.
в первом файле 66,444,33,2,432
во втором файле 1039,1984,1433
Затем беру первый файл. Сортирую его в памяти и вставляю в БД
2,33,66,432,444
Беру второй файл. Сортирую его в памяти и вставляю в БД
1039,1433,1984
Так нагляднее?
Диапазон значений 1-10000.
Разбиваю на 10 диапазонов 1-1000, 1001-2000,...,9001-10000.
Беру исходные данные и раскладываю по 10 файлам.
в первом файле 66,444,33,2,432
во втором файле 1039,1984,1433
Затем беру первый файл. Сортирую его в памяти и вставляю в БД
2,33,66,432,444
Беру второй файл. Сортирую его в памяти и вставляю в БД
1039,1433,1984
Так нагляднее?
+3
Ясно, понятно. Еще чисто утилитарный вопрос — чем сортировали параллельно? Я, к примеру, нагуглил готовые реализации многопоточного quicksort'а, но может, есть что лучше для этих целей.
0
Понял. Map-Reduce короче.
0
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Clustered index в InnoDB и оптимизация запросов