一、数据库索引
1、索引的种类
MySQL数据库的索引分类:
a.主键索引: 它是一种特殊的唯一索引,不允许有空值。一般是在建表的时候同时创建主键索引。
b.普通索引(Normal):最基本的MySQL数据库索引,它没有任何限制。
c.唯一索引(Unique):它与普通索引类似,不同的就是:MySQL数据库索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。
d.全文索引(Full Text ): 全文索引可以在varchar、char、text类型的列上创建。(mysql5.6版本以下的,全文索引不支持InnoDB存储引擎,需要修改为MySIAM)。
e.空间索引(SPATIAL):空间索引是对空间数据类型的字段建立的索引,空间索引只能在存储引擎为myISAM的表中创建。
2、添加索引的简单sql语句
-- 1.添加PRIMARY KEY(主键索引)
alter table `table_name[表名]` add primary key(`column`);
-- 2.添加UNIQUE(唯一索引)
alter table `table_name` add unique(`column`);
-- 3.添加普通索引
alter table `table_name` add index index_name(`column`);
-- 4.添加全文索引(了解)
alter table `table_name` add fulltext(`column`);
-- 5.添加多列索引(组合索引*)
alter table `table_name` add index index_name(`column1`,`column2`,`column3`);
3、索引的优点和缺点
(1)优点
a.唯一索引:保证数据唯一性,起到约束的作用。
b.其他索引:增加查询效率[只要是当做条件的字段包含索引,效率就会提高]。
(2)缺点
a.空间:创建索引需要占据磁盘的空间,如果有大量的索引,可能比数据文件更快达到最大文件大小
b.维护:创建索引和维护索引需要时间,而且数据量越大时间越长,维护:每次增加和删除,索引表会发生变化
4、索引的数据结构
(1)二叉查找树
缺点:
1.二叉树容易形成单链表使查询效率从O(log n)降低为O(n)
2.二叉树的数据都在节点上,每个节点上都只有一个数据,将数据加载到内存的同时,会加载很多次,会浪费io资源
(2)B-树
优点:
1.每个节点上有多个数据,相对于二叉树来说,就会有较少的io交互次数
2.b树的高度较低,如果要进行数据查询,会有较少的查询次数
(3)B+树
优点:[包含b树的优点]
1.数据都在叶子节点上[数据的最下层],非叶子节点只是存放了索引
2.在叶子节点上都有一个指针链[可以理解为一个地址值,一个指向],用来连接每个叶子节点,指针链的存在,可以让B+树数据结构的索引,在进行范围查询的时候,提高效率
(4)为什么B+树更适合做数据库索引 (最终原因:是为了提升查找效率)
1.查找数据最原始的是全盘扫描,但是如果对于几十万上百万数据查询的话,效率就很低了 [全盘扫描]
2.此时需要进行查找方式的优化,最熟悉的就是二叉树 [二叉树]
3.但是二叉树每个节点都是一个关键字,要把全部的索引关键字加载到内存,需要很大的内存开销,如果将一个节点读到内存中的一个盘块的话,B+树/B- 树 使用的盘块越少会进行更少的IO读写 [二叉树对内存开销大,B树和B+树对内存开销较小]
4. B- 树和 B+树的多路搜索树(多路的“多”是相对二叉树中的“二路”的)可以降低树的高度,只需要遍历非子叶节点,提高查找效率 [可以降低搜索树的高度,也就是可以进行少的if判断]
5.B- 树和 B+树之间,B+树所有叶子结点有一个链指针,范围统计效率更高,所以B+树更适合数据库索引的数据结构
[B+树存在链指针,能够更好的进行范围查询]
6.B+树查询效率比较稳定,每一次查询都是从根节点查询到叶子节点,并且每次的查询的长度相同,每个数据的查询效率相同,稳定的O(logn) [B+树查询的长度相同,查询效率更稳定]
5、什么时候使用索引 [索引的选择性]
索引的选择性是指索引列中不同值的数目与表中记录数的比,此属性是用来判断一个字段是否需要添加索引的关键.
如果一个表中有2000条记录,表索引列有1980个不同的值,那么这个索引的选择性就是1980/2000=0.99。一个索引的选择性越接近于1,这个索引的效率就越高。
6、索引什么时候会失效
(1)不要在查询中使用 !=、not in、not exists ,not ,<>
SELECT * FROM goods WHERE STATUS != 0
可优化为:
SELECT * FROM goods WHERE STATUS = 1 OR STATUS = 2
索引范围查询:[只适用于上面几个符号]
在学术界存在争论,查找的数据如果超过总数17%就不会使用索引并进行全表扫描[不是绝对的,只是其中之一]
自己试验的结果 : 查询SELECT * FROM student s WHERE s.score > 94范围的数据在8%-11%(11%就已经不走了,推测与数据量有关系)以下的情况下,会走索引
(2)不要在where条件的等号左侧中使用函数
SELECT * FROM goods WHERE YEAR (time) > = '2017'
可优化为:
SELECT * FROM goods WHERE time > = '2017-01-01'
对于带有列的函数计算,MySQL是无法使用索引的(Oracle可以使用函数索引)。在使用函数时,如SUBSTR函数,将'apple'更改为了'app',此时值发生了改变,导致之前设置的索引无效。
(3)MySQL支持后缀索引,但是不支持前缀索引【普通索引】*
CREATE FULLTEXT INDEX idx_info ON student(last_name) ;
SELECT * FROM goods WHERE NAME LIKE '%A'
可优化为:
SELECT * FROM goods WHERE NAME LIKE 'A%' // '%A%'
全文索引使用:【分词,倒序索引】搜索引擎 ES nosql
使用全文索引 跟普通索引稍有不同
使用全文索引的格式: MATCH (columnName) AGAINST ('string')
eg:
SELECT last_name from student where MATCH (last_name) AGAINST ('a')
当查询多列数据时:
建议在此多列数据上创建一个联合的全文索引,否则使用不了索引的。
SELECT * FROM `student` WHERE MATCH(`name`,`address`) AGAINST('b c')
(4)组合索引之最左前缀匹配原则*
设置联合索引时,索引的建立顺序要和where或者order by条件中的字段顺序相同,如建立name、status(分别为key1、key2)的联合索引,此时以name字段为第一查询顺序的索引有效:
在查询的条件中,没有最左边的字段,就不会走索引
a b c
where a = 1 and b =2 and c =2; //走索引
where b =2 and c =2;//不走索引
SELECT * FROM goods WHERE NAME = 'A' AND STATUS = 0
SELECT * FROM goods WHERE NAME = 'A'
查询条件没有最左边的字段就会失效:
SELECT * FROM goods WHERE STATUS = 0
最左前缀匹配原则的原理:
谁在最左边,谁就去索引树上面当查询条件
(5)where条件中有or,需将or中的每个字段都加上索引 [ 思考:and 会不会失效]*
and 一般来说不会失效
SELECT * FROM goods WHERE NAME = 'A' OR STATUS = 0
若仅设置 name 或 status 其中一个字段为索引,索引无效。
(6)当全表扫描速度比索引速度快时,mysql会使用全表扫描,此时索引失效,mysql自己去做
数据库数量太少时,mysql会认为不使用索引,效率较高
(7)数据类型不匹配*
当索引列的数据类型为字符型,按照数字查询会导致索引失效:
SELECT * FROM goods WHERE card = 1234567890
可更改为:
SELECT * FROM goods WHERE card = '1234567890'
通常情况下,当我们为字符类型的字段赋值时需要加入单引号,但是如果把一个纯数字的字符串赋值给一个字符型的字段时,可以不用加单引号,因为此时数据库系统会自动把这串数字转换为字符型数据。但当我们进行查询(where 条件中包含索引字段)时,如果采用纯数字,数据库会采用全表扫描,而非引用索引。我个人的理解是,可以将引号看做是一种函数,失效原因则与在 where条件左侧使用函数导致索引失效的原理相同。
二、SQL优化调优手段
sql调优
1、通过添加索引进行优化*
使用explain等工具分析SQL
添加索引
ALTER TABLE tb_menu ADD INDEX parent_id(parent_id);
explain命令查看一个这些SQL语句的执行计划,查看该SQL语句有没有使用上了索引,有没有做全表扫描
explain select 字段名 from 表名 order by 字段名 desc;
explain关键字段:
type:
system > const > eq_ref > ref > range > index > all
all (出现这个参数,说明,本语句需要优化)
对表访问方式,表示MySQL在表中找到所需行的方式,又称“访问类型”。
常用的类型有: ALL、index、range、 ref、eq_ref、const、system、NULL(从左到右,性能从差到好)
ALL:Full Table Scan, MySQL将遍历全表以找到匹配的行
index: Full Index Scan,index与ALL区别为index类型只遍历索引树
range:只检索给定范围的行,使用一个索引来选择行
ref: 表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值
eq_ref: 类似ref,区别就在使用的索引是唯一索引,对于每个索引键值,表中只有一条记录匹配,简单来说,就是多表连接中使用primary key或者 unique key作为关联条件
const、system: 当MySQL对查询某部分进行优化,并转换为一个常量时,使用这些类型访问。如将主键置于where列表中,MySQL就能将该查询转换为一个常量,system是const类型的特例,当查询的表只有一行的情况下,使用system
NULL: MySQL在优化过程中分解语句,执行时甚至不用访问表或索引,例如从一个索引列里选取最小值可以通过单独索引查找完成。
友情链接:
2.通过sql的修改进行语句优化
(1) SELECT语句务必指明字段名称【不允许 select * 】
SELECT*增加很多不必要的消耗(CPU、IO、内存、网络带宽);增加了使用覆盖索引的可能性;当表结构发生改变时,前断也需要更新。所以要求直接在select后面接上字段名。
(2) 用TRUNCATE 代替DELETE
TRUNCATE : 整个表删除,再创建表结构
DELETE: 逐条删除 ,可以回滚
(3) SQL语句中IN包含的值不应过多
MySQL对于IN做了相应的优化,即将IN中的常量全部存储在一个数组里面,而且这个数组是排好序的。但是如果数值较多,产生的消耗也是比较大的。再例如:select id from t where num in(1,2,3) 对于连续的数值,能用between就不要用in了;再或者使用连接来替换。
(4)注意范围查询语句*
思考:【使用in会索引失效么】 一般不会 ,如果in的多了可能就失效了 ,尽量不超过三个(实验 是可能 可能与字段有关系 3-6个才生效 第8个还没失效 有兴趣的同学可以试一下 不提供其他意见)
(当我根据姓氏字段查询的时候 in内两个值,不走索引而3个值起就开始走索引了 不是很理解,初步推辞 不是连续的)
一般来说:如果使用or 连接条件,尽量不要超过5个。否则可能索引失效;
[or通过试验得知,不是范围查询,条件查询]
对于联合索引来说,如果存在范围查询,比如between、>、<等条件时,会造成后面的索引字段失效。
(5)当只需要一条数据的时候,使用limit 1
这是为了使EXPLAIN中type列达到const类型
(6)如果排序字段没有用到索引,就尽量少排序
(7)limit 优化。使用合理的分页方式以提高分页的效率
使用下面SQL语句做分页的时候,可能有人会发现,随着表数据量的增加,直接使用limit分页查询会越来越慢。
select id,name from product limit 89757, 20
优化的方法如下:
可以取前一页的最大行数的id,然后根据这个最大的id来限制下一页的起点。比如此列中,上一页最大的 id 是89756。
SQL可以采用如下的写法: b+树的特性【指针链】
select id,name from product where id> 89756 limit 20 (并未实验过此优化)
(8)尽量使用inner join[where],避免left join:
参与联合查询的表至少为2张表,一般都存在大小之分。如果连接方式是inner join,在没有其他过滤条件的情况下MySQL会自动选择小表作为驱动表;但是left join在驱动表的选择上遵循的是左边驱动右边的原则,即left join左边的表名为驱动表。
(9)考虑在 where 及 order by 涉及的列上建立索引。
因地制宜,根据实际情况进行调整,因为有时索引太多也会降低性能。
order by的列尽量被索引。order by的列如果被索引,性能也会更好
(10)必要时可以使用force index来强制查询走某个索引*
有的时候MySQL优化器采取它认为合适的索引来检索SQL语句,但是可能它所采用的索引并不是我们想要的。
这时就可以采用force index来强制优化器使用我们制定的索引。
肥朝大佬友情链接: https://mp.weixin.qq.com/s/9X2FYKMfXVIx7IQbQaWZZw
数据库批量插入垃圾数据脚本【存储过程】
-- 创建存储过程
DROP PROCEDURE IF EXISTS add_student;
DELIMITER //
create PROCEDURE add_student(in num INT)
BEGIN
DECLARE rowid INT DEFAULT 0;
DECLARE firstname CHAR(1);
DECLARE name1 CHAR(1);
DECLARE name2 CHAR(1);
DECLARE lastname VARCHAR(3) DEFAULT '';
DECLARE sex CHAR(1);
DECLARE score INT DEFAULT 0;
DECLARE updateFirstName CHAR(1);
DECLARE updateLastName CHAR(1);
DECLARE updateScore INT DEFAULT 0;
SET @exedata = "";
WHILE rowid < num DO
SET firstname = SUBSTRING('赵钱孙李周吴郑王林杨柳刘孙陈江阮侯邹高彭徐',FLOOR(1+21*RAND()),1);
SET name1 = SUBSTRING('一二三四五六七八九十甲乙丙丁静景京晶名明铭敏闵民军君俊骏天田甜兲恬益依成城诚立莉力黎励',floor(1+43*RAND()),1);
SET name2 = SUBSTRING('一二三四五六七八九十甲乙丙丁静景京晶名明铭敏闵民军君俊骏天田甜兲恬益依成城诚立莉力黎励',floor(1+43*RAND()),1);
SET sex=SUBSTRING('男女',floor(1+2*RAND()),1);
SET score= FLOOR(40 + (RAND() *60));
SET lastname=SUBSTRING('一二三四五六七八九十甲乙丙丁静景京晶名明铭敏闵民军君俊骏天田甜雨恬益依娥我他刚人发上乐',floor(1+43*RAND()),1);
SET rowid = rowid + 1;
IF ROUND(RAND())=0 THEN
SET lastname =name1;
END IF;
IF ROUND(RAND())=1 THEN
SET lastname = CONCAT(name1,name2);
END IF;
IF length(@exedata)>0 THEN
SET @exedata = CONCAT(@exedata,',');
END IF;
SET @exedata=concat(@exedata,"('",firstname,"','",lastname,"','",sex,"','",score,"')");
IF rowid%10000=0
THEN
SET @exesql =concat("insert into student(first_name,last_name,sex,score) values ", @exedata);
prepare stmt from @exesql;
execute stmt;
DEALLOCATE prepare stmt;
SET @exedata = "";
END IF;
END WHILE;
IF length(@exedata)>0
THEN
SET @exesql =concat("insert into student(first_name,last_name,sex,score) values ", @exedata);
prepare stmt from @exesql;
execute stmt;
DEALLOCATE prepare stmt;
END IF;
END //
DELIMITER ;
执行存储过程
执行存储过程插入100万条数据:
call add_student(1000000);
实验用表结构(实验所用表与上述不同 发一样的会影响练习 在此上述一些表就不发了)
CREATE TABLE `student` (
`rowid` int(11) NOT NULL AUTO_INCREMENT,
`first_name` varchar(10) DEFAULT NULL,
`last_name` varchar(10) DEFAULT NULL,
`sex` varchar(2) DEFAULT NULL,
`score` int(11) DEFAULT NULL,
PRIMARY KEY (`rowid`) USING BTREE,
KEY `xing` (`first_name`),
KEY `ming` (`last_name`),
KEY `sex` (`sex`),
KEY `score` (`score`),
KEY `xingming` (`first_name`,`last_name`)
) ENGINE=InnoDB AUTO_INCREMENT=2000001 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=COMPACT;
SQL优化小题目
SELECT * FROM tb_menu WHERE id IN(
SELECT menu_id FROM tb_resource_menu WHERE resource_id IN (
SELECT resource_id FROM tb_role_resource WHERE role_id IN (
SELECT role_id FROM tb_admin_role WHERE admin_id IN (
SELECT id FROM tb_admin WHERE login_name='admin'
)
)
)
)
UNION
SELECT * FROM tb_menu WHERE id IN(
SELECT parent_id FROM tb_menu WHERE id IN(
SELECT menu_id FROM tb_resource_menu WHERE resource_id IN (
SELECT resource_id FROM tb_role_resource WHERE role_id IN (
SELECT role_id FROM tb_admin_role WHERE admin_id IN (
SELECT id FROM tb_admin WHERE login_name='admin'
)
)
)
)
)
UNION
SELECT * FROM tb_menu WHERE id IN (
SELECT parent_id FROM tb_menu WHERE id IN(
SELECT parent_id FROM tb_menu WHERE id IN(
SELECT menu_id FROM tb_resource_menu WHERE resource_id IN (
SELECT resource_id FROM tb_role_resource WHERE role_id IN (
SELECT role_id FROM tb_admin_role WHERE admin_id IN (
SELECT id FROM tb_admin WHERE login_name='admin'
)
)
)
)
)
);
表结构及其数据如下:
DROP TABLE IF EXISTS `tb_menu`;
CREATE TABLE `tb_menu` (
`id` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '菜单ID',
`name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '菜单名称',
`icon` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '图标',
`url` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT 'URL',
`parent_id` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '上级菜单ID',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Records of tb_menu
-- ----------------------------
INSERT INTO `tb_menu` VALUES ('1', '首页', 'iconHome', NULL, '0');
INSERT INTO `tb_menu` VALUES ('2', '商品', 'iconCommodity', NULL, '0');
INSERT INTO `tb_menu` VALUES ('2-1', '商品管理', 'iconSp', NULL, '2');
INSERT INTO `tb_menu` VALUES ('2-1-1', '商品列表', NULL, 'goods/goods.html', '2-1');
INSERT INTO `tb_menu` VALUES ('2-1-2', '添加商品', NULL, 'goods/goods_edit.html', '2-1');
INSERT INTO `tb_menu` VALUES ('2-1-3', '商品审核', NULL, 'goods/goods_audit.html', '2-1');
INSERT INTO `tb_menu` VALUES ('2-2', '商品配置', 'iconSeting', NULL, '2');
INSERT INTO `tb_menu` VALUES ('2-2-1', '商品分类', NULL, 'goods/category.html', '2-2');
INSERT INTO `tb_menu` VALUES ('2-2-2', '规格参数', NULL, 'goods/template.html', '2-2');
INSERT INTO `tb_menu` VALUES ('2-2-3', '品牌管理', NULL, 'goods/brand.html', '2-2');
INSERT INTO `tb_menu` VALUES ('2-2-4', '图片库管理', NULL, 'goods/album.html', '2-2');
INSERT INTO `tb_menu` VALUES ('3', '订单', 'iconOrder', NULL, '0');
INSERT INTO `tb_menu` VALUES ('3-1', '订单管理', NULL, '', '3');
INSERT INTO `tb_menu` VALUES ('3-1-1', '订单列表', NULL, 'order/order.html', '3-1');
INSERT INTO `tb_menu` VALUES ('3-1-2', '确认收货', NULL, 'order/order.html', '3-1');
INSERT INTO `tb_menu` VALUES ('3-1-3', '到货提醒', NULL, 'order/order_message.html', '3-1');
INSERT INTO `tb_menu` VALUES ('3-1-4', '订单设置', NULL, 'order/order_config.html', '3-1');
INSERT INTO `tb_menu` VALUES ('3-2-1', '退货申请处理', NULL, 'order/order.html', '3-2');
INSERT INTO `tb_menu` VALUES ('3-2-2', '退款申请处理', NULL, NULL, '3-2');
INSERT INTO `tb_menu` VALUES ('3-2-3', '退款原因设置', NULL, NULL, '3-2');
INSERT INTO `tb_menu` VALUES ('4', '库存', 'iconStock', NULL, '0');
INSERT INTO `tb_menu` VALUES ('4-1', '库存记录', NULL, NULL, '4');
INSERT INTO `tb_menu` VALUES ('4-1-1', '商品入库', NULL, NULL, '4-1');
INSERT INTO `tb_menu` VALUES ('4-1-2', '商品出库', NULL, NULL, '4-1');
INSERT INTO `tb_menu` VALUES ('5', '用户', 'iconUser', NULL, '0');
INSERT INTO `tb_menu` VALUES ('5-1', '用户管理', NULL, NULL, '5');
INSERT INTO `tb_menu` VALUES ('5-1-1', '用户列表', NULL, NULL, '5-1');
INSERT INTO `tb_menu` VALUES ('5-1-2', '用户等级设置', NULL, NULL, '5-1');
INSERT INTO `tb_menu` VALUES ('5-2', '成长值', NULL, NULL, '5');
INSERT INTO `tb_menu` VALUES ('5-2-1', '成长值查询', NULL, NULL, '5-2');
INSERT INTO `tb_menu` VALUES ('5-2-2', '任务奖励设置', NULL, NULL, '5-2');
INSERT INTO `tb_menu` VALUES ('6', '运营', 'iconOperate', NULL, '0');
INSERT INTO `tb_menu` VALUES ('6-1', '秒杀专区', NULL, NULL, '6');
INSERT INTO `tb_menu` VALUES ('6-1-1', '秒杀活动列表', NULL, NULL, '6-1');
INSERT INTO `tb_menu` VALUES ('6-1-2', '时间段列表', NULL, NULL, '6-1');
INSERT INTO `tb_menu` VALUES ('6-2', '满减专区', NULL, NULL, '6');
INSERT INTO `tb_menu` VALUES ('6-2-1', '满减活动列表', NULL, NULL, '6-2');
INSERT INTO `tb_menu` VALUES ('6-2-2', '添加满减活动', NULL, NULL, '6-2');
INSERT INTO `tb_menu` VALUES ('6-3', '优惠券管理', NULL, NULL, '6');
INSERT INTO `tb_menu` VALUES ('6-3-1', '优惠券列表', NULL, NULL, '6-3');
INSERT INTO `tb_menu` VALUES ('6-3-2', '添加优惠券', NULL, NULL, '6-3');
INSERT INTO `tb_menu` VALUES ('6-3-3', '优惠券查询', NULL, NULL, '6-3');
INSERT INTO `tb_menu` VALUES ('6-4', '活动管理', NULL, NULL, '6');
INSERT INTO `tb_menu` VALUES ('6-4-1', '活动列表', NULL, NULL, '6-4');
INSERT INTO `tb_menu` VALUES ('6-4-2', '添加活动', NULL, NULL, '6-4');
INSERT INTO `tb_menu` VALUES ('6-5', '广告管理', NULL, NULL, '6');
INSERT INTO `tb_menu` VALUES ('6-5-1', '广告列表', NULL, NULL, '6-5');
INSERT INTO `tb_menu` VALUES ('6-5-2', '添加广告', NULL, NULL, '6-5');
INSERT INTO `tb_menu` VALUES ('7', '统计', 'iconContent', NULL, '0');
INSERT INTO `tb_menu` VALUES ('7-1', '统计分析', NULL, NULL, '7');
INSERT INTO `tb_menu` VALUES ('7-1-1', '交易统计', NULL, NULL, '7-1');
INSERT INTO `tb_menu` VALUES ('7-1-2', '流量统计', NULL, NULL, '7-1');
INSERT INTO `tb_menu` VALUES ('7-1-3', '商品统计', NULL, NULL, '7-1');
INSERT INTO `tb_menu` VALUES ('7-1-4', '会员统计', NULL, NULL, '7-1');
INSERT INTO `tb_menu` VALUES ('7-1-5', '搜索统计', NULL, NULL, '7-1');
INSERT INTO `tb_menu` VALUES ('8', '财务', 'iconStatistics', NULL, '0');
INSERT INTO `tb_menu` VALUES ('8-1', '财务报表', NULL, NULL, '8');
INSERT INTO `tb_menu` VALUES ('8-1-1', '综合统计', NULL, NULL, '8-1');
INSERT INTO `tb_menu` VALUES ('8-1-2', '销售统计', NULL, NULL, '8-1');
INSERT INTO `tb_menu` VALUES ('8-2', '对账管理', NULL, NULL, '8');
INSERT INTO `tb_menu` VALUES ('8-2-1', '对账列表', NULL, NULL, '8-2');
INSERT INTO `tb_menu` VALUES ('9', '设置', 'iconSeting', NULL, '0');
INSERT INTO `tb_menu` VALUES ('9-1', '平台设置', NULL, NULL, '9');
INSERT INTO `tb_menu` VALUES ('9-1-1', '平台信息', NULL, NULL, '9-1');
INSERT INTO `tb_menu` VALUES ('9-1-2', '基本设置', NULL, NULL, '9-1');
INSERT INTO `tb_menu` VALUES ('9-1-3', '消息提醒', NULL, NULL, '9-1');
INSERT INTO `tb_menu` VALUES ('9-1-4', '验证码设置', NULL, NULL, '9-1');
INSERT INTO `tb_menu` VALUES ('9-2', '支付配送', NULL, NULL, '9');
INSERT INTO `tb_menu` VALUES ('9-2-1', '运费模板', NULL, NULL, '9-2');
INSERT INTO `tb_menu` VALUES ('9-2-2', '物流公司', NULL, NULL, '9-2');
INSERT INTO `tb_menu` VALUES ('9-2-3', '支付设置', NULL, NULL, '9-2');
INSERT INTO `tb_menu` VALUES ('9-2-4', '区域管理', NULL, NULL, '9-2');
INSERT INTO `tb_menu` VALUES ('9-3', '权限管理', NULL, NULL, '9');
INSERT INTO `tb_menu` VALUES ('9-3-1', '角色管理', NULL, NULL, '9-3');
INSERT INTO `tb_menu` VALUES ('9-3-2', '成员管理', NULL, NULL, '9-3');
INSERT INTO `tb_menu` VALUES ('9-3-3', '操作日志', NULL, NULL, '9-3');
SET FOREIGN_KEY_CHECKS = 1;
友情提示:可以尝试索引(本人使用添加索引的方式解决的 其余方式未试)