我有这个查询需要20秒才能运行...
SELECT books.id, books.title, books.slug, books.source_id, books.thumb_url
FROM books, book_cat
WHERE books.id = book_cat.book_id AND book_cat.cat_id = 158
ORDER BY books.id DESC LIMIT 50
book_cat
是book
和book_cats
book_cat
= 158
cat_id
中有39k行
有什么建议吗?
- 更新
所有PK,FK,索引(包括book_cat上的组合索引)都已到位。
BIGINT是的我知道,我期待很多书,很想改成INT。
UNIQUE键,它是PK的候选者
CREATE TABLE book_cat (
book_id BIGINT UNSIGNED NOT NULL,
cat_id SMALLINT UNSIGNED NOT NULL,
UNIQUE(book_id, cat_id),
CONSTRAINT FK_book_cat_1 FOREIGN KEY (book_id) REFERENCES books (id) ON DELETE CASCADE,
CONSTRAINT FK_book_cat_2 FOREIGN KEY (cat_id) REFERENCES book_cats (id)
) ENGINE = INNODB;
答案 0 :(得分:1)
在这种情况下,通常的罪魁祸首是没有具有适当值的索引。我会在book_cat上建议一个带有book_id和cat_id的索引。订单可能并不重要,但我首先使用的是更独特。
您可以尝试使用mySQL's EXPLAIN语句查看它将为您提供的信息。确保它使用预期的索引,或者创建一个索引,然后再试一次。
答案 1 :(得分:1)
首先,确保正确定义了表格。应将books.id
定义为主键。索引应该存在于book_cat.book_id
和book_cat.catid
上,因为它们似乎是其他表的外键。
如果这样做,那么对于你正在处理的记录数量,下面的SQL应该非常快。
SELECT books.id, books.title, books.slug, books.source_id, books.thumb_url
FROM books JOIN book_cat ON books.id = book_cat.book_id
WHERE book_cat.cat_id = 158
ORDER BY books.id DESC LIMIT 50
答案 2 :(得分:1)
首先,我要使用表别名和正确的join
语法重写您的查询:
SELECT b.id, b.title, b.slug, b.source_id, b.thumb_url
FROM books JOIN
book_cat bc
ON b.id = bc.book_id
WHERE bc.cat_id = 158
ORDER BY b.id DESC
LIMIT 50;
要优化此查询,请确保您在book_cat(book_id, cat_id)
和books(id)
上有索引。以下等效版本的查询可能会产生最佳计划:
SELECT b.id, b.title, b.slug, b.source_id, b.thumb_url
FROM books
WHERE EXISTS (SELECT 1 FROM book_cat bc WHERE b.id = bc.book_id AND bc.cat_id = 158)
ORDER BY b.id DESC
LIMIT 50;
此版本强调order by
可以使用索引,搜索类别应使用索引。