Задавайте вопросы, мы ответим
Вы не зашли.
Страниц: 1
Имеется словарь на несколько миллионов строк:
Неактивен
А тебе и правда нужен id?
Разумеется, нужен ключ на (id, word). И, если уникальность поддерживаешь
с помощью базы, остальные два тоже нужны
Неактивен
А тебе и правда нужен id?
Да, т.к. надо хранить обращения к словам.
Подумал тут, что можно сделать ключ на (id, word(1)). У одной буквы (грубо говоря) CARDINALITY около 30.
У меня проблемы возникают, когда надо вытащить ~1000 слов и больше. Если это количество уменьшить в 30 раз, то получится, в принципе, приемлемое значение
(это если он до выборки догадается отсортировать по индексу и LIMIT уже применть к проиндексированному, а не лезть в данные и только потом отсекать по LIMIT)
(хотя, может быть, эта проблема отпадет, т.к. вот)
Неактивен
Странно, что долго сортируется 1000 слов. Может быть плохая сама конструкция id IN (тысяча). Нельзя ли ее поменять на JOIN с временной таблицей?
Неактивен
Там дело не в самой сортировке, а в том, что надо сначала их все 1000 вытащить (таблица длинная, поэтому долго очень). А это обидно, т.к. из тысячи мне нужны 20. И если б он сначала сортировал, то вытаскивал бы 20, а не 1000.
Неактивен
Слова произвольные и нужно только 20? Можно пробовать делать AND word < 'бука', тогда точно будет отсекать. Если получится меньше 20, то повторить запрос.
Неактивен
Вообще идея дерзкая.. Но, боюсь, слишком неравномерным может оказаться распределение слов.
Короче. Лучше структуру базы оптимизировать, чем мы уже занимаемся в соседней теме.
Неактивен
Вопрос для ясности.
Запрос вида
WHERE id IN (много) или JOIN USING(id)
ORDER BY text
LIMIT X,Y
будет использовать ключ (id, text(N)) для LIMIT или будет вытаскивать все записи, соответствующие WHERE, а потом на них делать LIMIT?
Неактивен
Он знает список id, по любому id может выбирать последовательно в порядке возрастания text. Если сделать ORDER BY id,text, то тогда принципиально можно использовать ключ (но в данной задаче это бесполезно). В текущей постановке нужно делать сортировку отдельно (будет filesort).
Неактивен
Он знает список id, по любому id может выбирать последовательно в порядке возрастания text.
Так а почему он тогда не может остановить выборку, набрав нужное количество значений?
Неактивен
Вот ты взял id1 и его текст, затем id2 и его текст, потом id3 и его текст. Пусть у меня LIMIT 3 и я остановил выборку. Она получилась неотсортирована по полю text. А чтобы отсортировать, нужно выбрать сначала text для всех id, а потом выполнить filesort.
Вот пример. У тебя есть телефонный справочник (Фамилия, Имя, телефон) и ключ на нем (Фамилия, Имя). То есть отсротирован по Фамилии и в рамках каждой Фамилии по имени. Я тебе даю список фамилий (Скворцов, Дьяконов, Денисов, Иванов, Карпов, Станиславский, Тверской, Губкин) и прошу выбрать первые три в списке, остортированном по имени. Тебе придется найти их всех, а потом сортировать по имени.
Вот если бы я просил сортировку по Фамилии и Имени, то другое дело. Берем первую Фамилию и последовательно по Именам проходим и.т.д., останавливаем, когда набрали нужно количество записей. А тебе нужна сортировка, которой нет в индексе.
Неактивен
тебе нужна сортировка, которой нет в индексе.
Как же нет?
У меня индекс не только на Фамилию, но и на часть Имени.
Скворцов А
Дьяконов М
Денисов П
Иванов А
Карпов В
Станиславский Д
Тверской Б
Губкин П
Здесь же понятно, что первые три по имени - это Скворцов, Иванов и Тверской. Зачем лезть для всех восьмерых в базу, если известно, что понадобятся только три?
Или MySQL не может использовать для сортировки правую часть индекса?
Неактивен
В твоем примере как раз непонятно. Может быть Скворцовых несколько на букву А. Все равно ты сейчас сделал не операцию над индексом, а выбрал из индекса данные и сделал над ними filesort.
Операция над индексом это следующее.
а. Найти первую запись с минимальным значением индекса >= заданной константе
б. Найти следующую запись в порядке следования индекса
То, что ты предлагаешь, это некий хитрый алгоритм, который делает filesort сначала используя неполную информацию из индекса, а потом уже корректирует используя выборку данных. Такой алгоритм в MySQL не реализован.
Неактивен
Страниц: 1