Оптимизация нескольких SELECT - PullRequest
1 голос
/ 18 октября 2011
SELECT 
  (SELECT COUNT(*) FROM votes WHERE votes.vote = 1) AS upvotes,
  (SELECT COUNT(*) FROM votes WHERE votes.vote = -1) AS downvotes,
FROM votes WHERE link = <linkid>

Прямой вопрос;как это можно оптимизировать?Я не могу придумать лучшего способа сделать это, но я плохо в MySQL.

Спасибо за любые ответы!

РЕДАКТИРОВАТЬ: Чтобы было ясно:Я хочу, чтобы он возвращал одну строку с двумя столбцами;upvotes и downvotes

Ответы [ 6 ]

3 голосов
/ 18 октября 2011
SELECT sum(case when vote = 1 then 1 end) as upvotes,
    sum(case when vote = -1 then 1 end) as downvotes
FROM votes
WHERE link = < linkid >
2 голосов
/ 18 октября 2011

Попробуйте использовать СУММУ вместо СЧЕТА:

SELECT 
  SUM(vote = 1) AS upvotes,
  SUM(vote = -1) AS downvotes
FROM votes WHERE link = <linkid>

Обратите внимание, что не дает тот же результат, что и отправленный вами запрос. Я думаю, что вы отправили запрос неправильно !

1 голос
/ 18 октября 2011

ИМХО, вам не нужно рассчитывать общее количество голосов на лету вообще .Вместо этого вам следует сохранить общее количество голосов с данным элементом и использовать подробный журнал голосования в качестве инструмента для обеспечения целостности результатов и предоставления пользователям возможности отозвать голос.

1 голос
/ 18 октября 2011

Полагаю, что все комментаторы означали, что ваш запрос, вероятно, должен быть:

SELECT 
  (SELECT COUNT(*) FROM votes WHERE link = <linkid> AND vote = 1 ) AS upvotes,
  (SELECT COUNT(*) FROM votes WHERE link = <linkid> AND vote = -1) AS downvotes

К настоящему времени у вас есть как минимум 4 других способа, которые делают то же самое, что и этот (3 способа точно так же и 1 способ слегкаразные, дают одинаковые результаты, но в 2 ряда).Протестируйте свои данные и выберите более быстрый (или оставьте их все и повторите тест позже, когда таблица станет больше).

Составной индекс на (link,vote) также будет полезен для всех версий.

1 голос
/ 18 октября 2011
SELECT 
  COUNT(case vote when  1 then 1 else null end) AS upvotes,
  COUNT(case vote when -1 then 1 else null end) AS downvotes
FROM votes WHERE link = <linkid>

Время для изучения: count учитывает только ненулевые значения, поэтому всякий раз, когда вы видите, then 1 также может быть then 'Yay!'.Нули не учитываются.

1 голос
/ 18 октября 2011

Я бы использовал это:

SELECT COUNT(*), vote AS numvotes FROM votes WHERE vote = -1 OR vote = 1 GROUP BY vote
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...