简体   繁体   English

如何有效地创建索引

[英]How to create indexes efficiently

I wish to know how I can create indexes in my database according to my data structure. 我想知道如何根据我的数据结构在数据库中创建索引。 most of my queries are fetching data against the ID and the name as well with two or three tables joining while pagination. 我的大多数查询都是根据ID和名称来获取数据的,同时在分页时还要连接两个或三个表。 please advise how to make indexes according to below queries. 请根据以下查询建议如何建立索引。

Query:1 查询:1

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

Explain: 说明:

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

Query:2 查询: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 

Explain: 说明:

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

Can i use indexes for pagination in offset case where same query returns total: 在相同查询返回总计的偏移量情况下,我可以使用索引进行分页吗:

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 

Do I need to update my queries after creating indexes. 创建索引后是否需要更新查询。 please also suggest what should be the table format. 还请提出表格格式应该是什么。

SHOW CREATE TABLE books: 显示创建表的书:

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
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)

Do you really need LEFT JOIN ? 您真的需要LEFT JOIN吗? If you can change it to JOIN , the optimizer might be able to start with authors . 如果可以将其更改为JOIN ,则优化程序可能可以从authors开始。 If it does, then 如果有的话

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

My cookbook for building indexes. 的建立索引食谱

Other tips: 其他提示:

  • INT(100) and INT(2) are identical -- each is a 4-byte signed integer. INT(100)INT(2) 相同 -每个都是4字节有符号整数。 Read about TINYINT UNSIGNED for numbers 0..255, etc. Use that for your flags (status, is_scroll, etc) 阅读有关TINYINT UNSIGNED的数字0..255等的信息。将其用于您的标志(状态,is_scroll等)
  • DATE is a datatype; DATE是一种数据类型; using a VARCHAR is problematic if you ever want to compare or order. 如果您想比较或订购,使用VARCHAR是有问题的。
  • Learn about composite indexes, such as my first example. 了解复合索引,例如我的第一个示例。

Your display widths are a little funky, but that wont cause a problem. 您的显示宽度有点时髦,但这不会引起问题。

Query 1: 查询1:

  • You're using the LIKE operator without a wildcard search % . 您正在使用的LIKE运算符没有通配符搜索% You can likely swap this with an = operator. 您可以将其与=运算符交换。
  • I don't see the column type in your SHOW CREATE TABLE -- but it seems you don't have an index here, unless you renamed it to faith . 我在您的SHOW CREATE TABLE中看不到列type -但似乎您这里没有索引,除非您将其重命名为faith
  • Do you need to type to be a string? 您需要输入字符串吗? could it be abstracted to a types table and then joined against using an integer? 是否可以将其抽象到types表,然后使用整数进行联接? Or, if you have a fixed amount of types that's unlikely to change, could you use an enum ? 或者,如果您有固定数量的类型无法更改,是否可以使用enum

Query 2: 查询2:

  • You don't need to quote strings, also that's probably vulnerable to SQL injection. 您不需要引用字符串,这也很容易受到SQL注入的影响。 do ='.intval($id).' ='.intval($id).' instead. 代替。
  • Make sure you have an index on authors.aid and that they're of the same type. 确保您在authors.aid上具有索引,并且它们具有相同的类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM