我的查询很慢。
SELECT
posts.*
FROM
posts
INNER JOIN categories ON posts.category_id = categories.id
AND categories.main = 1
AND(categories.private_category = 0
OR categories.private_category IS NULL)
WHERE
posts.id NOT IN('')
AND posts.deleted = 0
AND posts.hidden = 0
AND posts.total_points >= - 5
ORDER BY
posts.id DESC
LIMIT 10;
所以在我解释之后:
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
|----|-------------|-------------|------------|------|------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------|---------|-------------------------------|-------|----------|----------------------------------------------|
| 1 | SIMPLE | categories | | ALL | PRIMARY,index_categories_on_private_category | | | | 12 | 10.00 | Using where; Using temporary; Using filesort |
| 1 | SIMPLE | posts | | ref | PRIMARY,index_posts_on_category_id,index_posts_on_deleted_and_hidden_and_user_id_and_created_at,index_posts_deleted,index_posts_hidden,index_posts_total_points | index_posts_on_category_id | 5 | mydb.categories.id | 37516 | 12.50 | Using index condition; Using where |
我在categories.main
上添加了索引:
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
|----|-------------|-------------|--------|------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|---------|-----------------------------------|-------|-------------|
| 1 | SIMPLE | posts | range | PRIMARY,index_posts_on_category_id,index_posts_on_deleted_and_hidden_and_user_id_and_created_at,index_posts_deleted,index_posts_hidden,index_posts_total_points | PRIMARY | 4 | | 37516 | Using where |
| 1 | SIMPLE | categories | eq_ref | PRIMARY,index_categories_on_private_category,index_categories_on_main | PRIMARY | 4 | mydb.posts.category_id | 12 | Using where |
它表明它不使用indexing(?)。查询仍然很慢,我想对其进行优化。查询出了什么问题?
修改
posts表如何创建:
CREATE TABLE `posts` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`user_id` int(11) DEFAULT NULL,
`category_id` int(11) DEFAULT NULL,
`title` varchar(1000) NOT NULL,
`content` text,
`total_points` int(11) DEFAULT '0',
`deleted` tinyint(1) DEFAULT '0',
`hidden` tinyint(1) DEFAULT '0',
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `index_posts_on_category_id` (`category_id`),
KEY `index_posts_created_at` (`created_at`),
KEY `index_posts_on_deleted_and_hidden_and_user_id_and_created_at` (`deleted`,`hidden`,`user_id`,`created_at`),
KEY `index_posts_deleted` (`deleted`),
KEY `index_posts_hidden` (`hidden`),
KEY `index_posts_total_points` (`total_points`),
KEY `index_posts_user_id` (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=304063 DEFAULT CHARSET=utf8
这是类别表的创建方式:
CREATE TABLE `categories` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(100) NOT NULL,
`main` tinyint(1) DEFAULT '0',
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`hidden` tinyint(1) DEFAULT '0',
`private_category` tinyint(1) DEFAULT '0',
PRIMARY KEY (`id`),
KEY `index_categories_on_private_category` (`private_category`),
KEY `index_categories_on_main` (`main`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8
答案 0 :(得分:1)
由于使用OR条件,查询速度很慢:
categories.private_category = 0 OR categories.private_category IS NULL
MySQL必须扫描categories
表中的所有记录