如何高效地创建索引
How to create indexes efficiently
我想知道如何根据我的数据结构在我的数据库中创建索引。我的大部分查询都是根据 ID 和名称获取数据,以及在分页时加入两个或三个 table。请告知如何根据以下查询制作索引。
查询: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
在相同查询 returns 总计:
的偏移量情况下,我可以使用索引进行分页吗
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
创建索引后是否需要更新我的查询。还请建议 table 格式应该是什么。
显示创建 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
您的显示宽度有点古怪,但这不会造成问题。
查询 1:
- 您使用的
LIKE
运算符没有通配符搜索 %
。您可以将其与 =
运算符交换。
- 我在你的 SHOW CREATE TABLE 中没有看到列
type
-- 但你似乎没有索引,除非你将它重命名为 faith
.
- 需要输入字符串吗?它可以抽象为
types
table 然后加入反对使用整数吗?或者,如果您有固定数量且不太可能更改的类型,您可以使用 enum
?
查询 2:
- 您不需要引用字符串,这也可能容易受到 SQL 注入的攻击。改为
='.intval($id).'
。
- 确保您在
authors.aid
上有一个索引,并且它们属于同一类型。
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 字节有符号整数。阅读有关数字 0..255 等的 TINYINT UNSIGNED
。将其用于您的标志(状态、is_scroll 等)
DATE
是一种数据类型;如果您想比较或订购,使用 VARCHAR
是有问题的。
- 了解复合索引,比如我的第一个例子。
我想知道如何根据我的数据结构在我的数据库中创建索引。我的大部分查询都是根据 ID 和名称获取数据,以及在分页时加入两个或三个 table。请告知如何根据以下查询制作索引。
查询: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
在相同查询 returns 总计:
的偏移量情况下,我可以使用索引进行分页吗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
创建索引后是否需要更新我的查询。还请建议 table 格式应该是什么。
显示创建 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
您的显示宽度有点古怪,但这不会造成问题。
查询 1:
- 您使用的
LIKE
运算符没有通配符搜索%
。您可以将其与=
运算符交换。 - 我在你的 SHOW CREATE TABLE 中没有看到列
type
-- 但你似乎没有索引,除非你将它重命名为faith
. - 需要输入字符串吗?它可以抽象为
types
table 然后加入反对使用整数吗?或者,如果您有固定数量且不太可能更改的类型,您可以使用enum
?
查询 2:
- 您不需要引用字符串,这也可能容易受到 SQL 注入的攻击。改为
='.intval($id).'
。 - 确保您在
authors.aid
上有一个索引,并且它们属于同一类型。
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 字节有符号整数。阅读有关数字 0..255 等的TINYINT UNSIGNED
。将其用于您的标志(状态、is_scroll 等)DATE
是一种数据类型;如果您想比较或订购,使用VARCHAR
是有问题的。- 了解复合索引,比如我的第一个例子。