Такие поисковые системы, как Google, используют очень сложные закулисные алгоритмы для индексации поисковых запросов.По сути, они уже определили, какие слова встречаются на каждой странице, а также относительную важность этих слов и относительную важность страниц (по сравнению с другими страницами).Эти индексы очень быстрые, потому что они основаны на побитовом индексировании .
Рассмотрим следующие поиски в Google:
custom : 542 million google hits
pager : 10.8 m
custom pager 1.26 m
По сути, они создали запись для слова custom, и в этой записи они поместили 1 для каждой страницы, которая ее содержит, и0 для каждой страницы, которая не содержит его.Затем они застегивают его, потому что их намного больше, чем единиц.Они делают то же самое для пейджера.
Когда приходит поиск custom pager
, они распаковывают обе записи, выполняют битовую операцию И над ними, и это приводит к массиву битов, где длина - это общее количество страниц, которыеони проиндексированы, а число 1 представляет количество совпадений для поиска.Позиция каждого бита соответствует конкретному результату, который известен заранее, и им нужно только просмотреть все подробности первых 10, чтобы отобразить на первой странице.
Это слишком упрощено, но этоосновной принцип.
О, да, у них также есть огромные банки серверов, выполняющих индексацию, и огромные банки серверов, отвечающих на поисковые запросы.ОГРОМНЫЕ банки серверов!
Это делает их намного быстрее, чем все, что можно сделать в реляционной базе данных.
Теперь к вашему вопросу: не могли бы вы вставить образец SQL, чтобы мы посмотрелиat?
Одна вещь, которую вы можете попробовать, - это изменить порядок отображения таблиц и объединений в вашем выражении SQl.Я знаю, что кажется, что это не должно иметь никакого значения, но это, безусловно, может.Если вы поместите наиболее ограничивающие объединения ранее в операторе, то в итоге вы можете получить меньше общих объединений, выполненных в базе данных.
Пример из реального мира.Скажем, вы хотели найти все записи в телефонной книге под именем «Джонсон», с номером, начинающимся с «7».Один из способов - найти все числа, начинающиеся с 7, а затем соединить их с числами, принадлежащими людям по имени Джонсон.На самом деле фильтрацию можно было бы выполнить намного быстрее, даже если у вас была индексация как по именам, так и по номерам.Это связано с тем, что имя «Джонсон» является более ограничительным, чем число 7.
Таким образом, порядок имеет значение, и программное обеспечение базы данных не всегда хорошо определяет заранее, какие объединения выполняются первыми.Я не уверен насчет MySQL, так как мой опыт в основном связан с SQL Server, который использует статистику индекса для расчета порядка выполнения соединений.Эти статистические данные устаревают после ряда вставок, обновлений и удалений, поэтому их необходимо периодически пересчитывать.Если в MySQL есть что-то похожее, вы можете попробовать это.
ОБНОВЛЕНИЕ Я посмотрел на ваш запрос, который вы разместили.Десять левых объединений не являются чем-то необычным и должны работать хорошо, если у вас есть нужные индексы.Ваш не сложный запрос.
Что вам нужно сделать, это разбить этот запрос до его основ.Закомментируйте соединения поиска, например, для валюты, course_stats, стран, штатов и городов вместе с соответствующими полями в операторе select.Это все еще работает так медленно?Возможно нет.Но это, вероятно, все еще не идеально.
Так что комментируйте все остальное, пока у вас не будут только курсы и группа по идентификатору курса и порядок по Courseid.Затем поэкспериментируйте с добавлением левых объединений, чтобы увидеть, какое из них оказывает наибольшее влияние.Затем, сосредоточив внимание на тех из них, которые оказывают наибольшее влияние на производительность, измените порядок запросов.Это метод проб и ошибок.Было бы намного лучше взглянуть на индексы столбцов, к которым вы присоединяетесь.
Например, для строки cm.method_id = c.method_id
потребуется первичный ключ для course_methodologies.method_id и индекс внешнего ключа для courses.method_id и так далее. Кроме того, все поля в предложениях where, group by и order by нуждаются в индексах.
Удачи
ОБНОВЛЕНИЕ 2
Вы серьезно должны посмотреть на фильтрацию даты по этому запросу. Что ты пытаешься сделать?
AND ((('2010-09-01 00:00:00' <= esched.date_start
AND esched.date_start <= '2010-09-25 00:00:00')
OR ('2010-09-01 00:00:00' <= esched.date_end
AND esched.date_end <= '2010-09-25 00:00:00'))
OR ((esched.date_start <= '2010-09-01 00:00:00'
AND '2010-09-01 00:00:00' <= esched.date_end)
OR (esched.date_start <= '2010-09-25 00:00:00'
AND '2010-09-25 00:00:00' <= esched.date_end)))
Может быть переписано как:
AND (
//date_start is between range - fine
(esched.date_start BETWEEN '2010-09-01 00:00:00' AND '2010-09-25 00:00:00')
//date_end is between range - fine
OR (esched.date_end BETWEEN '2010-09-01 00:00:00' AND '2010-09-25 00:00:00')
OR (esched.date_start <= '2010-09-01 00:00:00' AND esched.date_end >= '2010-09-01 00:00:00' )
OR (esched.date_start <= '2010-09-25 00:00:00' AND esched.date_end > = '2010-09-25 00:00:00')
)