如何有效地创建索引

时间:2015-06-05 03:47:42

标签: mysql indexing

我希望知道如何根据我的数据结构在数据库中创建索引。我的大多数查询都是根据ID和名称获取数据,以及在分页时加入两个或三个表。请根据以下查询建议如何制作索引。

查询:1

SELECT DISTINCT topic, type FROM books where type like 'Tutor-Books' order by topic

说明:

id  select_type table   type    possible_keys   key key_len ref rows    Extra   
1   SIMPLE  books   range   faith   faith   102 NULL    132 Using index condition; Using temporary; Using filesort

查询:2

SELECT  books.name, books.name2, books.id, books.image, books.faith,
        books.topic, books.downloaded, books.viewed, books.language,
        books.size, books.author as author_id, authors.name as author_name,
        authors.aid
    from  books
    LEFT JOIN  authors ON books.author = authors.aid
    WHERE  books.id = '".$id."'
      AND  status = 1 

解释:

id  select_type table   type    possible_keys   key key_len ref rows    Extra   
1   SIMPLE  books   const   PRIMARY PRIMARY 4   const   1   NULL
1   SIMPLE  authors const   aid aid 4   const   1   NULL

我可以在相同查询返回总计的偏移量情况下使用索引进行分页:

SELECT  SQL_CALC_FOUND_ROWS books.name, books.name2, books.id,
        books.image, books.topic, books.author as author_id,
        authors.name as author_name, authors.aid
    from  books
    LEFT JOIN  authors ON books.author = authors.aid
    WHERE  books.author = '$pid'
      AND  status = 1
    ORDER BY  books.name
    LIMIT  $limit OFFSET $offset 

创建索引后是否需要更新查询?请同时建议表格格式。

SHOW CREATE TABLE书籍:

Table   Create Table    
books   CREATE TABLE `books` (
 `name` varchar(100) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
 `name2` varchar(150) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
 `author` int(100) NOT NULL,
 `translator` int(120) NOT NULL,
 `publisher` int(100) NOT NULL,
 `pages` int(50) NOT NULL,
 `date` varchar(50) CHARACTER SET latin1 NOT NULL,
 `downloaded` int(100) NOT NULL,
 `alt_lnk` text NOT NULL,
 `viewed` int(100) NOT NULL,
 `language` varchar(100) CHARACTER SET latin1 NOT NULL,
 `image` varchar(200) CHARACTER SET latin1 NOT NULL,
 `faith` varchar(100) CHARACTER SET latin1 NOT NULL,
 `id` int(100) NOT NULL AUTO_INCREMENT,
 `sid` varchar(1200) CHARACTER SET latin1 DEFAULT NULL,
 `topic` varchar(100) CHARACTER SET latin1 NOT NULL,
 `last_viewed` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
 `size` double NOT NULL,
 `status` int(2) NOT NULL DEFAULT '0',
 `is_scroll` int(2) NOT NULL,
 `is_downloaded` int(2) NOT NULL,
 `pdf_not_found` int(2) NOT NULL,
 PRIMARY KEY (`id`),
 KEY `name` (`name`),
 KEY `downloaded` (`downloaded`),
 KEY `name2` (`name2`),
 KEY `topic` (`topic`),
 KEY `faith` (`faith`)
) ENGINE=InnoDB AUTO_INCREMENT=12962 DEFAULT CHARSET=utf8

2 个答案:

答案 0 :(得分:1)

where type like 'Tutor-Books' order by topic  (or:)
where type   =  'Tutor-Books' order by topic
--> INDEX(type, topic)

where type like '%Tutor-Books' order by topic
--> INDEX(topic) -- the leading % prevents indexing

LEFT JOIN  authors ON books.author = authors.aid
--> PRIMARY KEY(aid)

你真的需要LEFT JOIN吗?如果您可以将其更改为JOIN,则优化程序可能会以authors开头。如果是,那么

--> INDEX(author) -- in `books`

My cookbook用于构建索引。

其他提示:

  • INT(100)INT(2) 相同 - 每个都是一个4字节有符号整数。阅读TINYINT UNSIGNED,了解数字0..255等。用于标志(状态,is_scroll等)
  • DATE是一种数据类型;如果您想要比较或订购,使用VARCHAR会有问题。
  • 了解复合索引,例如我的第一个示例。

答案 1 :(得分:0)

您的显示宽度有点时髦,但这不会引起问题。

查询1:

  • 您使用LIKE运算符时没有通配符搜索%。您可以使用=运算符交换它。
  • 我没有在您的SHOW CREATE TABLE中看到列type - 但是这里似乎没有索引,除非您将其重命名为faith
  • 你需要输入一个字符串吗?是否可以将其抽象为types表,然后使用整数加入?或者,如果您有不可能更改的固定数量的类型,您可以使用enum吗?

查询2:

  • 您不需要引用字符串,也可能容易受到SQL注入攻击。改为='.intval($id).'
  • 确保您在authors.aid上有一个索引,并且它们的类型相同。