# 索引 * * * * * 在讲索引之前需要构建一个演示表,这里拿构建演示表的过程顺便讲下数据写入优化。 先创建演示订单表,SQL如下 ~~~ SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for `ob_order` -- ---------------------------- DROP TABLE IF EXISTS `ob_order`; CREATE TABLE `ob_order` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `member_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '充值会员id', `order_sn` char(50) COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT '订单号', `order_money` decimal(10,2) unsigned NOT NULL DEFAULT '0.00' COMMENT '订单金额', `pay_money` decimal(10,2) unsigned NOT NULL DEFAULT '0.00' COMMENT '支付金额', `pay_status` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '支付状态 0:未支付 1:已支付', `pay_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '支付时间', `create_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间', `update_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '更新时间', `status` tinyint(2) unsigned NOT NULL DEFAULT '1' COMMENT '状态', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2358136 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='测试订单表'; -- ---------------------------- -- Records of ob_order -- ---------------------------- ~~~ ### 数据写入优化 * * * * * 此处使用向订单表插入2万条数据来作为演示。 **未优化前的代码如下** ~~~ $obj = get_sington_object('obIdWork', \ob\IdWork::class); debug('test_insert_begin'); for($i = 0; $i < 20000; $i++) { $order['member_id'] = (int) $i / 10 + 1; $order['order_sn'] = date("YmdHis").$obj->nextId(); $order['order_money'] = rand(10000,99999); $order['pay_money'] = 0; $order['pay_status'] = 0; $order['pay_time'] = 0; $order['update_time'] = 0; $order['status'] = 0; $this->modelOrder->addInfo($order); } debug('test_insert_end'); dump(debug('test_insert_begin', 'test_insert_end')); ~~~ ![](https://box.kancloud.cn/91291b00ebabad0183b00e0c00149f88_681x149.jpg) 下面附带的是执行后的信息,执行时间是545秒,内存消耗是11072KB。 **优化后的代码如下** ~~~ $obj = get_sington_object('obIdWork', \ob\IdWork::class); debug('test_insert_begin'); $order_list = []; for($i = 0; $i < 20000; $i++) { $order['member_id'] = (int) $i / 10 + 1; $order['order_sn'] = date("YmdHis").$obj->nextId(); $order['order_money'] = rand(10000,99999); $order['pay_money'] = 0; $order['pay_status'] = 0; $order['pay_time'] = 0; $order['update_time'] = 0; $order['status'] = 0; $order_list[] = $order; } $this->modelOrder->setList($order_list); debug('test_insert_end'); dump(debug('test_insert_begin', 'test_insert_end')); ~~~ ![](https://box.kancloud.cn/2bc922ef23edafebcaf8519bf03716e5_659x146.jpg) 可以看到两段代码都是向订单表中插入2万条数据,第一段代码**用时 545秒,内存消耗11072KB**,第二段代码**用时 13秒,内存消耗11382KB**,为什么差距会这么大? **原因**:第一段循环操作写入order,第二段将order先通过PHP循环放入order_list然后再一次写入。 ### 索引 * * * * * 作者为了演示索引的威力,先提前在订单表中创建了 500多万条数据,来看看下面的查询。 ![](https://box.kancloud.cn/d9544f0f3e50e0ba5feffb58b32c6a2c_1157x270.jpg) 可以看到单条数据的查询已经达到了 3.5秒,若在加上一些业务逻辑可能造成多次DB操作,速度可想而知。 下面在查询的两个字段上建立索引 ![](https://box.kancloud.cn/57752b7962a330f8e82169c82e39700a_690x112.jpg) 索引建立好后,再来执行下刚才的操作,查询条件与记录数量一模一样的情况下。 ![](https://box.kancloud.cn/e109a240e96eb43305d950eb68ef09c4_1136x246.jpg) 没有看错,这就是索引的威力,3.5秒变0.001秒,1.4秒变0.1秒。 从上面的测试可以看出,索引用的好数据再大也不怕咯。^_^