Esta consulta:
SELECT *
FROM listings
WHERE (publishedon BETWEEN 1441105258 AND 1443614458) AND
(published = 1) AND
(cat_id in (1,2,3,4,5)) AND
(source_id in (1,2,3,4,5));
Es difícil de optimizar solo con índices. El mejor índice es el que comienza con published
y luego tiene las otras columnas; no está claro cuál debería ser su orden. La razón es porque todos menos published
no están usando =
.
Debido a que su problema de rendimiento está en una ordenación, eso sugiere que se están devolviendo muchas filas. Por lo general, se usa un índice para satisfacer el WHERE
cláusula antes de que el índice pueda usarse para el ORDER BY
. Eso hace que esto sea difícil de optimizar.
Sugerencias . . Ninguno es tan bueno:
- Si va a acceder a los datos por mes, podría considerar particionar los datos por mes. Eso hará la consulta sin
ORDER BY
más rápido, pero no ayudará alORDER BY
. - Pruebe varios órdenes de columnas después de
published
en el índice. Es posible que encuentre la(s) columna(s) más selectiva(s). Pero, una vez más, esto acelera la consulta antes de la clasificación. - Piense en formas de estructurar la consulta para tener más condiciones de igualdad en el
WHERE
o para devolver un conjunto de datos más pequeño. - (No muy recomendado) Poner un índice en
published
y la columna de pedidos. Luego use una subconsulta para obtener los datos. Poner las condiciones de desigualdad (IN
y así sucesivamente) en la consulta externa. La subconsulta usará el índice para ordenar y luego filtrará los resultados.
La razón por la que no se recomienda el último es porque SQL (y MySQL) no garantizan el orden de los resultados de una subconsulta. Sin embargo, debido a que MySQL materializa subconsultas, los resultados realmente están en orden. No me gusta usar efectos secundarios no documentados, que pueden cambiar de una versión a otra.