Следующий запрос зависит от таблицы с ~ 4 тыс. Строк в таблице links
и ~ 40 тыс. Строк в таблице comments
и в настоящее время занимает около 0,2 с, что кажется довольно медленным, учитывая, что не много данных.
SELECT
t1.id, t1.url, t1.dateAdded
FROM links AS t1 LEFT JOIN
comments AS t2
ON (t1.id = t2.linkId)
WHERE
COALESCE(t2.dateAdded, t1.dateAdded) <= "2020-03-22 20:04:45"
GROUP BY t1.id
ORDER BY
COALESCE(
(
SELECT
MAX(dateAdded)
FROM comments
WHERE
linkId = t1.id AND
dateAdded <= "2020-03-22 20:04:45"
),
t1.dateAdded
) DESC,
t1.id DESC
LIMIT 10
t1.id
- первичный ключ, t2.linkId
- внешний ключ; Я также попытался добавить индекс для dateAdded
в обеих таблицах, но, похоже, это не помогло.
Просто, чтобы определить узкое место, я перебил запрос к следующему и заметил, что при упорядочении по t1.dateAdded
запрос занимает 0,12 с, тогда как при упорядочении по t1.id
он занимает всего 0,003 с
SELECT
t1.id, t1.url, t1.dateAdded
FROM links AS t1 LEFT JOIN
comments AS t2
ON (t1.id = t2.linkId)
WHERE
COALESCE(t2.dateAdded, t1.dateAdded) <= "2020-03-22 20:04:45"
GROUP BY t1.id
ORDER BY
t1.id DESC -- here I tried both t1.dateAdded and t1.id
Поэтому я попытался найти разницу с помощью EXPLAIN
, и, похоже, единственная разница заключается в Extra
поле, где для ORDER BY t1.id
оно пустое, а для ORDER BY t1.dateAdded
это Using temporary; Using filesort
(обратите внимание, что у меня индекс на t1.dateAdded
). К сожалению, я застрял в интерпретации того, что это значит, и в целом, как оптимизировать исходный запрос. Обратите внимание, что id
- это INT(10)
, а dateAdded
- это DATETIME
.
В целом, цель, которую я хотел бы достичь, - это упорядочить ссылки так, чтобы новейшие ссылки или ссылки с новыми комментариями вверху, где «новейший» означает относительно предоставленного времени (т.е. не учитывает ссылки / комментарии, добавленные после этого).
Заранее благодарен за любую помощь или подсказки
РЕДАКТИРОВАТЬ: Добавление более подробная информация
EXPLAIN
для скрытого запроса с t1.id
+------+-------------+-------+-------+---------------+------------+---------+--------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+-------+---------------+------------+---------+--------------+------+-------------+
| 1 | SIMPLE | t1 | index | NULL | PRIMARY | 4 | NULL | 3674 | |
| 1 | SIMPLE | t2 | ref | fk_link_id | fk_link_id | 5 | db1.t1.id | 8 | Using where |
+------+-------------+-------+-------+---------------+------------+---------+--------------+------+-------------+
EXPLAIN
для скрытого запроса с t1.dateAdded
+------+-------------+-------+-------+---------------+------------+---------+--------------+------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+-------+---------------+------------+---------+--------------+------+---------------------------------+
| 1 | SIMPLE | t1 | index | NULL | PRIMARY | 4 | NULL | 3674 | Using temporary; Using filesort |
| 1 | SIMPLE | t2 | ref | fk_link_id | fk_link_id | 5 | db1.t1.id | 8 | Using where |
+------+-------------+-------+-------+---------------+------------+---------+--------------+------+---------------------------------+
Информация о links
таблица:
CREATE TABLE `links` (
`id` int(10) UNSIGNED NOT NULL,
`url` varchar(2083) CHARACTER SET utf8mb4 NOT NULL,
`dateAdded` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
ALTER TABLE `links`
ADD PRIMARY KEY (`id`),
ADD KEY `dateAdded` (`dateAdded`);
информация о comments
таблица:
CREATE TABLE `comments` (
`id` int(10) UNSIGNED NOT NULL,
`linkId` int(10) UNSIGNED DEFAULT NULL,
`userId` int(10) UNSIGNED NOT NULL,
`content` varchar(2000) CHARACTER SET utf8mb4 NOT NULL,
`dateAdded` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
ALTER TABLE `comments`
ADD PRIMARY KEY (`id`),
ADD KEY `fk_link_id` (`linkId`);
ALTER TABLE `comments`
ADD CONSTRAINT `fk_link_id` FOREIGN KEY (`linkId`) REFERENCES `links` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;