MySQL: JOIN & использование индекса в запросе ORDER BY - PullRequest
0 голосов
/ 02 ноября 2010

У меня есть система, похожая на функцию вопросов и ответов в stackoverflow. Основное отличие состоит в том, что каждый вопрос имеет дату окончания срока действия:

CREATE TABLE questions (
     id INT NOT NULL AUTO_INCREMENT,
     title CHAR(100) NOT NULL,
     details TEXT
     PRIMARY KEY (id)
) 

CREATE TABLE answers (
     id INT NOT NULL AUTO_INCREMENT,
     question_id INT NOT NULL
     details TEXT
     expiration_datetime DATETIME
     score INT
     PRIMARY KEY (id)
) 

Я хочу отобразить вопрос вместе с N первыми не просроченными ответами, упорядоченными по баллам. Я думаю что-то вроде этого:

SELECT * FROM questions, answers 
WHERE questions.id=1 AND questions.id=answers.question_id AND answers.expiration_datetime > NOW() 
ORDER BY answers.score DESC LIMIT 10

Несколько вопросов:

1) Является ли запрос выше наиболее эффективным способом сделать то, что я хочу? Чем он отличается от явного использования JOIN, например:

SELECT * FROM questions JOIN answers ON questions.id=answers.question_id
WHERE questions.id=1 AND answers.expiration_datetime > NOW() 
ORDER BY answers.score DESC LIMIT 10

2) Как заставить мой запрос использовать индекс? Я думаю добавить этот индекс в ответы ТАБЛИЦА:

INDEX (question_id, expiration_datetime, score)

Будет ли вышеуказанный индекс работать для моего запроса? Это не кажется правильным, потому что expiration_datetime идет по возрастанию, а мне нужно, чтобы счет был по убыванию. Что я могу сделать здесь?

1 Ответ

0 голосов
/ 02 ноября 2010

Объединение таблиц с INNER JOIN или в предложении FROM дает тот же план выполнения.Тем не менее, первый намного легче читать (и это стандарт предлагает с 1992 года).

Ваша СУБД будет использовать индекс, когда это возможно.Обычно рекомендуется напечатать план выполнения (EXPLAIN SELECT * FROM -- ...).Однако обратите внимание, что создание индекса с несколькими столбцами может быть сложным.В вашем случае вы можете использовать индекс для question_id, но , а не в expiration_datetime или score, поскольку они не являются первыми столбцами индекса.Вам придется сделать три разных индекса.

PS SELECT * не рекомендуется.Всегда вводите нужные вам столбцы (легко читаемые и перечитываемые) и упоминайте только те столбцы, которые вы будете использовать.Нет смысла выбирать, например, initial_date, если вы никогда не используете этот столбец в своем скрипте!

...