013_索引

1. 索引介绍

1.1. 您可以在表中创建索引, 以便更加快速高效地查询数据。

1.2. 打个比方, 如果合理的设计且使用索引的MySQL是一辆兰博基尼的话, 那么没有设计和使用索引的MySQL就是一个人力三轮车。

1.3. 用户无法看到索引, 它们只能被用来加速搜索/查询。

1.4. 索引分单列索引和组合索引。单列索引, 即一个索引只包含单个列。组合索引, 即一个索引包含多个列。

1.5. 创建索引时, 你需要确保该索引是应用在SQL查询语句的条件(一般作为where子句的条件)。

1.6. 实际上, 索引也是一张表, 该表保存了主键与索引字段, 并指向实体表的记录。

1.7. 上面都在说使用索引的好处, 但过多的使用索引将会造成滥用。因此索引也会有它的缺点: 虽然索引大大提高了查询速度, 同时却会降低更新表的速度, 如对表进行insert、update和delete。因为更新表时, MySQL不仅要保存数据, 还要保存一下索引文件。

1.8. 建立索引会占用磁盘空间的索引文件。

2. 普通索引

2.1. 这是最基本的索引, 它没有任何限制。

2.2. 创建普通索引

create index `indexname` on `tablename` (`columnname`);

2.3. 修改表结构添加普通索引

alter table `tablename` add index `indexname` (`columnname`);

2.4. 创建表的时候直接指定

create table `tablename` (  

`id` int(11) not null,   

`username` varchar(16) not null,   

index `indexname` (`username`)   

);  

3. 唯一索引

3.1. 唯一索引与普通索引类似, 不同的就是索引列的值必须唯一, 但允许有空值。如果是组合索引, 则列值的组合必须唯一。

3.2. 创建唯一索引

create unique `indexname` on `tablename` (`columnname`);

3.3. 修改表结构添加唯一索引

alter table `tablename` add unique index `indexname` (`columnname`);

3.4. 创建表的时候直接指定

create table `tablename` (  

`id` int(11) not null,   

`username` varchar(16) not null,   

unique `indexname` (`username`)   

);  

4. 删除索引

4.1. drop index `indexname` on `tablename`;

4.2. alter table `tablename` drop index `indexname`;

5. 显示索引信息

5.1. 你可以使用show index命令来列出表中的相关的索引信息。可以通过添加\G来格式化输出信息。

show index from `tablename`; \G

6. 索引查询

6.1. 创建一张Persons表, 同时插入400多万条数据。

drop table if exists `persons`;
create table `persons` (
  `id` int(11) not null,
  `lastname` varchar(255) not null,
  `firstname` varchar(255) default null,
  `address` varchar(255) default null,
  `city` varchar(255) default null
) engine=innodb default charset=utf8;


insert into `persons` values ('1', 'san', 'zhang', 'china', 'luoyang');
insert into `persons` values ('2', 'san', 'zhang', 'china', 'luoyang');
insert into `persons` values ('3', 'san', 'zhang', 'china', 'luoyang');
insert into `persons` values ('4', 'san', 'zhang', 'china', 'luoyang');
insert into `persons` values ('5', 'san', 'zhang', 'china', 'luoyang');
insert into `persons` values ('6', 'san', 'zhang', 'china', 'luoyang');
insert into `persons` values ('7', 'san', 'zhang', 'china', 'luoyang');
insert into `persons` values ('8', 'san', 'zhang', 'china', 'luoyang');
insert into `persons` values ('9', 'san', 'zhang', 'china', 'luoyang');
......
insert into `persons` values ('3999990', 'san', 'zhang', 'china', 'luoyang');
insert into `persons` values ('3999991', 'san', 'zhang', 'china', 'luoyang');
insert into `persons` values ('3999992', 'san', 'zhang', 'china', 'luoyang');
insert into `persons` values ('3999993', 'san', 'zhang', 'china', 'luoyang');
insert into `persons` values ('3999994', 'san', 'zhang', 'china', 'luoyang');
insert into `persons` values ('3999995', 'san', 'zhang', 'china', 'luoyang');
insert into `persons` values ('3999996', 'san', 'zhang', 'china', 'luoyang');
insert into `persons` values ('3999997', 'san', 'zhang', 'china', 'luoyang');
insert into `persons` values ('3999998', 'san', 'zhang', 'china', 'luoyang');
insert into `persons` values ('3999999', 'san', 'zhang', 'china', 'luoyang');
insert into `persons` values ('4000000', 'san', 'zhang', 'china', 'luoyang');

6.2. 没有使用索引, 查询Persons表的第3000000条数据, 耗时3秒多。

6.3. 给Persons表添加索引。

6.4. 添加索引后, 再次查询Persons表的第3000000条数据, 耗时0秒。

<think>我们已经在之前的对话中明确了GBase8a数据库不支持直接为视图创建索引。因此,优化视图查询性能的核心在于优化视图所依赖的基表以及优化视图定义本身。根据用户提供的引用[1](DEV05GBase8aMPPCluster数据库性能优化)和引用[4](创建视图CREATEVIEW)中的信息,结合GBase8a的特性,我们可以采取以下优化策略:###1.**优化基表索引**-在视图所依赖的基表(如`v_xmsjbhtjb`,`st_yqhz_xmbhqkb_02`,`st_yqhz_xmbhqkb_05`,`std_013_yqhz_xmxx`等)上创建合适的索引。-重点考虑在连接条件(如`gzds`)和过滤条件(如`fybtbzb_nd`,`fxmxx_kgnd`等)上创建索引。-根据引用[1],GBase8a支持智能索引(SmartIndex)和哈希索引(HashIndex),选择适当的索引类型:-**智能索引**:适用于高基数列(唯一值多的列),如主键或唯一标识列。-**哈希索引**:适用于等值查询(如`WHEREa.fybtbzb_nd='2025'`)的连接列。-创建索引示例:```sql--在st_yqhz_xmbhqkb_02表的fybtbzb_nd和gzds列上创建哈希索引CREATEINDEXidx_st_yqhz_xmbhqkb_02_fybtbzb_nd_gzdsONst_yqhz_xmbhqkb_02(fybtbzb_nd,gzds)USINGHASH;``````sql--在st_yqhz_xmbhqkb_05表的fxmxx_kgnd和gzds列上创建哈希索引CREATEINDEXidx_st_yqhz_xmbhqkb_05_fxmxx_kgnd_gzdsONst_yqhz_xmbhqkb_05(fxmxx_kgnd,gzds)USINGHASH;```###2.**优化视图定义**-**减少嵌套子查询**:用户视图使用了4个LEFTJOIN子查询,每个子查询内部又进行了聚合(GROUPBY)。考虑将子查询改写为公共表表达式(CTE)或临时表,以提升可读性和执行效率。-**避免不必要的列**:确保视图中只包含必要的列,减少数据传输和计算量。-**合并过滤条件**:视图外层WHERE条件(`v.fybtbzb_nd='2025'`)可以下推到基表查询中,但用户已经在子查询中使用了类似的过滤条件(如`a.fybtbzb_nd='2025'`)。确保所有可下推的条件都已下推。改写视图示例(使用CTE):```sqlCREATEORREPLACEVIEWst_yqhz_xmbgqkb_03ASWITHq1AS(SELECTa.gzds,COUNT(a.fid)ASxmgs1,ROUND(SUM(a.sjwctze)/10000,2)AStzgm1FROMst_yqhz_xmbhqkb_02aWHEREa.fybtbzb_nd='2025'GROUPBYa.gzds),q2AS(SELECTa.gzds,COUNT(a.fid)ASxmgs2,COALESCE(SUM(b.fxmxx_tzgm),0)AStzgm2FROMst_yqhz_xmbhqkb_05aLEFTJOINstd_013_yqhz_xmxxbONa.fid=b.fidWHEREa.fxmxx_kgnd='2025'GROUPBYa.gzds),q3AS(SELECTa.gzds,COUNT(a.fid)ASxmgs3,COALESCE(SUM(b.fxmxx_tzgm),0)AStzgm3FROMst_yqhz_xmbhqkb_01aLEFTJOINstd_013_yqhz_xmxxbONa.fid=b.fidWHEREa.fxmxx_wgnd='2025'GROUPBYa.gzds),q4AS(SELECTa.gzds,COUNT(a.fid)ASxmgs4,COALESCE(SUM(b.fxmxx_tzgm),0)AStzgm4FROMst_yqhz_xmbhqkb_04aLEFTJOINstd_013_yqhz_xmxxbONa.fid=b.fidWHEREa.fxmxx_qynd='2025'GROUPBYa.gzds)SELECT'2025'asrq,ROW_NUMBER()OVER(ORDERBYv.dspx)ASxh,v.dspx,v.gzds,q1.xmgs1,q1.tzgm1,q2.xmgs2,q2.tzgm2,q3.xmgs3,q3.tzgm3,q4.xmgs4,q4.tzgm4FROMv_xmsjbhtjbvLEFTJOINq1ONv.gzds=q1.gzdsLEFTJOINq2ONv.gzds=q2.gzdsLEFTJOINq3ONv.gzds=q3.gzdsLEFTJOINq4ONv.gzds=q4.gzdsWHEREv.fybtbzb_nd='2025'GROUPBYv.gzds,v.dspx,q1.xmgs1,q1.tzgm1,q2.xmgs2,q2.tzgm2,q3.xmgs3,q3.tzgm3,q4.xmgs4,q4.tzgm4ORDERBYxh;```###3.**使用物化视图(如果支持)**-如果GBase8a版本支持物化视图(MaterializedView),则可以将视图创建为物化视图,并定期刷新。这样查询将直接访问预计算好的数据,极大提升性能。-创建物化视图示例(语法可能因版本而异):```sqlCREATEMATERIALIZEDVIEWmv_st_yqhz_xmbgqkb_03BUILDIMMEDIATE|DEFERRED--立即构建或延迟构建REFRESHFAST|COMPLETE|FORCE--刷新方式AS--这里是原视图的SELECT语句;```-注意:物化视图会占用存储空间,且需要维护刷新策略。###4.**分析执行计划**-使用`EXPLAIN`命令分析视图查询的执行计划(引用[1]中提到EXPLAIN使用指南):```sqlEXPLAINSELECT*FROMst_yqhz_xmbgqkb_03;```-根据执行计划,检查是否存在全表扫描(TABLESCAN)或性能瓶颈步骤,并针对性地优化。###5.**分区和分片优化**-如果基表数据量巨大,考虑使用GBase8a的分区(Partitioning)或分片(Sharding)特性(引用[2]中提到的分布式架构),将数据分布到不同节点,提升并行查询能力。###6.**统计信息更新**-确保基表的统计信息是最新的,以便优化器生成高效的执行计划:```sqlANALYZETABLEst_yqhz_xmbhqkb_02UPDATESTATISTICS;```###总结优化视图查询性能的关键步骤:1.**基表索引优化**:在连接列和过滤列上创建合适的索引(智能索引或哈希索引)[^1]。2.**视图定义优化**:简化嵌套查询,使用CTE提高可读性和执行效率。3.**物化视图**:如果支持,使用物化视图存储预计算结果。4.**执行计划分析**:通过`EXPLAIN`定位瓶颈。5.**数据分布优化**:利用分布式架构进行分区/分片。6.**更新统计信息**:保证优化器决策准确。§§相关问题§§1.GBase8a中如何创建和使用物化视图?2.如何分析GBase8a中SQL语句(包括视图查询)的执行计划?3.GBase8a的智能索引和哈希索引有什么区别?各自适用于什么场景?[^1]4.在GBase8a的基表上创建索引有哪些最佳实践和注意事项?[^1]5.使用GBaseDataStudio等工具进行数据库性能调优的具体步骤是什么?[^5]</think>在 GBase 8a MPP Cluster 中优化视图查询速度,虽然无法直接为视图创建索引,但可通过以下核心策略实现性能提升: ### 一、基表索引优化(最关键)[^1] 1. **连接条件索引** 在视图依赖的基表连接列上创建智能索引或哈希索引: ```sql -- 在 v_xmsjbhtjb 的 gzds 列创建索引 CREATE INDEX idx_vxmsjbhtjb_gzds ON v_xmsjbhtjb(gzds) USING HASH; -- 在 st_yqhz_xmbhqkb_02 的 fybtbzb_nd 和 gzds 列创建复合索引 CREATE INDEX idx_st02_fy_gzds ON st_yqhz_xmbhqkb_02(fybtbzb_nd, gzds) USING SMART; ``` 2. **过滤条件索引** 为 WHERE 子句中的高频过滤列创建索引: ```sql -- 各子查询的过滤列 CREATE INDEX idx_st05_kgnd ON st_yqhz_xmbhqkb_05(fxmxx_kgnd) USING SMART; CREATE INDEX idx_st01_wgnd ON st_yqhz_xmbhqkb_01(fxmxx_wgnd) USING HASH; ``` ### 二、视图定义优化 1. **减少嵌套查询** 将子查询转换为 CTE(公共表表达式): ```sql CREATE OR REPLACE VIEW st_yqhz_xmbgqkb_03 AS WITH q1 AS (SELECT ... FROM st_yqhz_xmbhqkb_02 WHERE ...), q2 AS (SELECT ... FROM st_yqhz_xmbhqkb_05 WHERE ...) SELECT '2025' as rq, ROW_NUMBER() OVER(ORDER BY v.dspx) AS xh, ... FROM v_xmsjbhtjb v LEFT JOIN q1 ON ... LEFT JOIN q2 ON ... WHERE v.fybtbzb_nd = '2025'; ``` 2. **避免重复计算** 移除不必要的 `GROUP BY`(外层 GROUP BY 在视图定义中可能冗余): ```sql -- 删除最后的 GROUP BY 子句 SELECT ... FROM v_xmsjbhtjb v LEFT JOIN (...) q1 ON ... ... WHERE v.fybtbzb_nd = '2025' -- GROUP BY v.gzds, v.dspx, ... -- 移除此行 ORDER BY xh; ``` ### 三、使用物化视图(若版本支持)[^1] ```sql CREATE MATERIALIZED VIEW mv_st_yqhz_xmbgqkb_03 REFRESH COMPLETE ON DEMAND -- 全量刷新 AS SELECT ... -- 原视图定义 ``` ### 四、分布式执行优化[^1] 1. **数据分布策略** 确保基表使用合理的 DISTRIBUTED BY 子句,使关联表分布键一致: ```sql ALTER TABLE v_xmsjbhtjb DISTRIBUTE BY HASH(gzds); ALTER TABLE st_yqhz_xmbhqkb_02 DISTRIBUTE BY HASH(gzds); ``` 2. **执行计划分析** 使用 EXPLAIN 诊断性能瓶颈: ```sql EXPLAIN SELECT * FROM st_yqhz_xmbgqkb_03; ``` 重点关注: - `TABLE SCAN` 是否转为 `INDEX SCAN` - 是否存在数据重分布(REDISTRIBUTED) ### 五、其他优化手段 1. **统计信息更新** 定期更新表统计信息: ```sql ANALYZE TABLE st_yqhz_xmbhqkb_02 UPDATE STATISTICS; ``` 2. **分区裁剪** 若基表按年份分区,确保过滤条件触发分区裁剪: ```sql -- 建表时分区 CREATE TABLE st_yqhz_xmbhqkb_02 ( ... ) PARTITION BY KEY(fybtbzb_nd) PARTITIONS 10; ``` ### 优化效果验证 通过 GBaseDataStudio 监控工具[^5]: 1. 对比优化前后查询耗时 2. 观察集群各节点负载均衡 3. 检查内存和CPU使用峰值 > **关键原则**:视图性能优化本质是优化其底层查询。在 GBase 8a 中,**基表索引优化**和**分布式执行计划调优**是提升视图查询速度最有效的手段[^1][^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值