наиболее оптимизированный способ выбора «помеченных сообщений» с использованием where & limit в базе данных mysql - PullRequest
0 голосов
/ 06 ноября 2010

У меня следующая структура таблицы:


+----------+------------------------+------+-----+------------------------------------------+----------------+
| Field    | Type                   | Null | Key | Default                                  | Extra          |
+----------+------------------------+------+-----+------------------------------------------+----------------+
| id       | int(10) unsigned       | NO   | PRI | NULL                                     | auto_increment |
| body     | varchar(200)           | NO   |     | Hey now!                                 |                |
| flags    | int(10) unsigned       | NO   |     | 0                                        |                |
| views    | int(10) unsigned       | NO   |     | 1                                        |                |
+----------+------------------------+------+-----+------------------------------------------+----------------+

и я хочу выбрать «только те строки, которые не были отмечены более чем на 5% их общего количества просмотров и были просмотрены не менее 5 раз».

Вот мой запрос:


SELECT id,body
FROM tablename
WHERE id NOT IN (
    SELECT id
    FROM tablename
    WHERE flags/views * 100 > 5.0
    AND views > 5
    ORDER BY id DESC
)
ORDER BY id DESC
LIMIT 6

Я думаю, что выбор «каждой отдельной строки, которая помечена более чем на 30% от общего числа просмотров», потребует огромных накладных расходов, особенно когда таблица увеличивается до очень большого числа строк. Может ли кто-нибудь помочь мне оптимизировать это?

Я также думал о создании столбца «flag_score» и просто обновлял его каждый раз, когда что-то помечено, таким образом, я мог просто выбирать столбец flag_score вместо выполнения математических операций внутри выбора (и сохранять свой дополнительный запрос выбора ). Это звучит как хороший подход? Спасибо большое.

Редактировать: Другая проблема, с которой я столкнулся, заключается в том, что если я просто сделаю что-то вроде:


SELECT *
FROM tabelname
WHERE flags/views * 100 > 5.0
AND views > 5
ORDER BY id DESC
LIMIT 5

... если 4 из 5 сообщений помечены, он вернет только 1 строку! И я хотел бы, чтобы оператор возвращал 5 строк.

Ответы [ 2 ]

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

Я бы сказал, что кеширование - это разумный подход, но все зависит от того, что такое чтение / запись в вашей системе. Если люди все время помечают, значение flag_score нужно будет обновлять каждый раз, так что ваша дорогая операция будет происходить много раз.

Отдельно я не уверен, что вы получите повышение производительности, но вы могли бы сделать флажок / views> .05, чтобы сохранить умножение каждого запроса, хотя я не ожидаю, что эта часть будет такой дорогой.

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

Математика не очень дорогая, поэтому, если у вас меньше, скажем, 100 000 записей, вы можете делать это без беспокойства.

Как вы сами можете предложить, вы всегда можете кэшироватьусловие:

UPDATE tablename
SET is_over_30_percent = (flags/views * 100 > 5.0)
WHERE id='id_of_updated_entry'

, что дает преимущество в том, что вы можете поместить индекс в * is_over_30_percent *, чтобы запрос вообще не работал.

Не забудьте поместить комбинированный индекс в * id_of_updated_entry * и дата и id , поэтому индекс можно использовать для выбора и заказа (ORDER BY стоит дорого).

...