# 索引
* * * * *
在講索引之前需要構建一個演示表,這里拿構建演示表的過程順便講下數據寫入優化。
先創建演示訂單表,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'));
~~~

下面附帶的是執行后的信息,執行時間是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'));
~~~

可以看到兩段代碼都是向訂單表中插入2萬條數據,第一段代碼**用時 545秒,內存消耗11072KB**,第二段代碼**用時 13秒,內存消耗11382KB**,為什么差距會這么大?
**原因**:第一段循環操作寫入order,第二段將order先通過PHP循環放入order_list然后再一次寫入。
### 索引
* * * * *
作者為了演示索引的威力,先提前在訂單表中創建了 500多萬條數據,來看看下面的查詢。

可以看到單條數據的查詢已經達到了 3.5秒,若在加上一些業務邏輯可能造成多次DB操作,速度可想而知。
下面在查詢的兩個字段上建立索引

索引建立好后,再來執行下剛才的操作,查詢條件與記錄數量一模一樣的情況下。

沒有看錯,這就是索引的威力,3.5秒變0.001秒,1.4秒變0.1秒。
從上面的測試可以看出,索引用的好數據再大也不怕咯。^_^
- 序言
- 基礎
- 安裝環境
- 安裝演示
- 規范
- 目錄
- 介紹
- 后臺介紹
- 后臺首頁
- 會員管理
- 系統管理
- 系統設置與配置管理
- 菜單管理
- 系統回收站
- 服務管理
- 插件管理
- 文章管理
- 接口管理
- 優化維護
- SEO管理
- 數據庫
- 文件清理
- 行為日志
- 執行記錄
- 統計分析
- 接口介紹
- 接口文檔
- 錯誤碼設計
- Token介紹
- 前臺介紹
- 架構
- 架構總覽
- 生命周期
- 入口文件
- 模塊設計
- 依賴注入
- 控制器架構
- 邏輯架構
- 驗證架構
- 服務架構
- 模型架構
- 行為架構
- 插件架構
- 配置
- 配置介紹
- 配置加載
- 配置擴展
- 請求
- 請求信息
- 日志
- 后臺行為日志
- 系統執行日志
- 框架日志
- 數據
- 數據庫設計
- 數據字典
- 數據庫操作
- 事務控制
- 混合操作
- 實戰
- 控制器
- 邏輯與驗證
- 視圖與模型
- 插件研發
- 服務研發
- 接口研發
- 雜項
- 數據導入導出
- 二維碼條形碼
- 郵件發送
- 云存儲服務
- 支付服務
- 短信服務
- 微信分享
- 生成海報
- 聊天室
- PJAX
- Demo
- Widget
- 附錄
- 常量參考
- 配置參考
- 函數參考
- 進階
- Redis
- 自動緩存
- 全自動緩存
- 索引
- 數據簽名
- 全自動事務
- 隊列