如何确保查询使用索引?

时间:2019-05-30 12:08:44

标签: mysql

我的查询很慢。

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

1 个答案:

答案 0 :(得分:1)

由于使用OR条件,查询速度很慢:

categories.private_category = 0 OR categories.private_category IS NULL

MySQL必须扫描categories表中的所有记录