数据库执行一条SQL的顺序大致如下:
FROM → WHERE → GROUP BY → 聚合函数(SUM/AVG/COUNT等) → SELECT → ORDER BY
不同字段位置建索引的效果总结
| 字段位置 | 原因 |
|---|---|
| WHERE 等值条件(=) | 索引直接精确定位,效率最高 |
| WHERE 范围条件(>、<、BETWEEN、LIKE '张%') | 索引可缩小范围,但范围后的字段无法继续使用索引 |
| GROUP BY 字段 | 索引可避免排序(Sort),分组效率高 |
| ORDER BY 字段 | 索引可避免排序(Sort) |
| JOIN 连接字段 | 索引可大幅提升连接效率 |
在SQL Server 数据库中存在销售单据明细表,其建表语句为:
sql
CREATE TABLE 销售单据明细表
(
销售单据编号 varchar(8),
商品编号 varchar(8),
单价 int,
数量 int,
总价 int
);
真考题库试卷1
(1)在系统运行一段时间后,此表中有近千万条数据,在数据库中需要执行如下SQL语句:
sql
SELECT 商品编号, SUM(总价)
FROM 销售单据明细表
WHERE 单价 > 50
GROUP BY 商品编号;
(2)为了提高系统的可靠性和性能,某工程师提出将原有单机运行的SQL Server改为Active-Standby架构的数据库运行模式,如下图所示:

(3)在运行过程中,发现此系统数据库服务器IO很忙,业务人员反映系统运行速度慢。为了提高系统运行速度,在不修改应用程序的前提下,两位工程师提出了不同的解决方案,且两种方案存储空间均满足存储容量需求:
① 不改变硬盘数量,将硬盘RAID模式从RAID5改为RAID0。
② 不改变硬盘数量,将硬盘RAID模式从RAID5改为RAID10。
- 在(1)中,在"销售单据明细表"中的"单价"列上建立索引可以提高该查询效率 √
WHERE 范围条件加索引可缩小范围- 情况(1)中,在"销售单据明细表"中的"总价"列上建立索引可以提高查询效率 ×
聚合函数(SUM/AVG/COUNT等)里的字段,建单独索引是无效的- 在(1)中,在"销售单据明细表"中的"商品编号"列上建立索引不能提高该查询效率 ×
GROUP BY 字段加索引可避免排序- 在(1)中,在"销售单据明细表"中的(单价,商品编号)列上建立复合索引不能提高查询效率 ×
- 在(2)中,采用此架构不能提高系统性能 √
- 在(2)中,采用此架构可以提高系统可靠性 √
- 情况(3)中,两种方案均能提高数据写性能 √
RAID0和RAID10的写性能比RAID5高- 情况(2)中,两种方案均能提高数据可靠性 ×
方案①中,RAID0的可靠性比RAID5低
| RAID级别 | 别称 | 数据分布方式 | 冗余性 | 读性能 | 写性能 | 存储利用率 | 可靠性指标 |
|---|---|---|---|---|---|---|---|
| RAID0 | 条带化(Striping) | 数据分块分散写入所有盘 | 无 | 高 | 高 | 100% | 极低(无容错,任意一盘损坏即数据全丢) |
| RAID1 | 镜像(Mirroring) | 所有盘写入完全相同数据 | 有(单盘故障可恢复) | 高 | 一般 | 50% | 较高 |
| RAID5 | 带奇偶校验的条带化 | 数据分块+奇偶校验信息分散存储 | 有(可坏1盘) | 较高 | 较低(需计算校验) | (n-1)/n | 中等偏低 |
| RAID10 | 镜像+条带化(RAID1+0) | 先做镜像,再做条带 | 有(每镜像组可坏1盘) | 极高 | 较高 | 50% | 极高 |
(4)在运行过程中,发现此系统数据库CPU使用率很高,达到近95%,高峰期间达到100%,且系统内存使用率达到90%,但系统I/O很轻。业务人员反映系统操作速度慢。为了提高系统运行速度,在不修改应用程序的前提下,两位工程师提出了两种不同的解决方案:
方案一:为服务器增加1颗CPU
方案二:为服务器增加一倍内存
考虑成本因素,现阶段只能选择一种方案实施。
1.情况(4)中,系统CPU使用率高是影响系统性能的主要问题。 √
已知系统数据库CPU使用率很高,达到近95%,高峰期间达到100%,而系统I/O很轻。这表明CPU资源成为了系统性能的瓶颈,系统CPU使用率高是影响系统性能的主要问题
情况(4)中,因为系统I/O很轻,所以增加内存对提高系统运行速度作用不大。 √
情况(4)中,考虑现有情况,方案一增加CPU更合理。 √
真考题库试卷2
为了保持数据一致性,该表上设置了一个触发器以保证每条数据满足约束:总价 = 单价 × 数量。
在系统运行一段时间后,此表中有近千万条数据。
(1)程序员在数据库中执行如下SQL语句速度缓慢:
sql
SELECT 商品编号, SUM(数量)
FROM 销售单据明细表
WHERE 总价 > 200
GROUP BY 商品编号;
(2)为解决以上问题,进行了一些优化工作,设优化后以上SQL语句执行效率可以满足需求。但是发现系统的其他功能仍运行缓慢,数据库管理员检查服务器运行情况,数据表明:
I. 服务器CPU使用率不超过30%。
II. 服务器内存128GB,已使用内存不超过3GB。
III. 数据库数据量100GB,系统I/O很重,主要为磁盘读操作。
- 情况(1)中,在"销售单据明细表"中的"总价"列上建立索引可以提高该查询效率。 √
WHERE 范围条件加索引可缩小范围- 情况(1)中,在"销售单据明细表"中的"商品编号"列上建立索引不能提高查询效率。 ×
GROUP BY 字段加索引可避免排序- 情况(1)中,将"销售单据明细表"中的触发器改为在程序中进行总价计算,可以提高查询效率。 ×
- 情况(2)中,系统I/O很重是影响系统性能的主要问题。 √
- 情况(2)中,数据量只有100GB,系统内存有128GB,因此无需购买新硬件,乙工程:师方案比较合理。 √
真考题库试卷3
某学校的学籍管理系统使用SQL Server数据库。在数据库中有学生基本信息表,建表语句为:
sql
CREATE TABLE 学生基本信息表
(
学号 varchar(10),
姓名 varchar(50),
性别 varchar(2),
系所号 varchar(8),
是否有学籍 varchar(2)
);
由于该表数据量较大,因此建立学生基本信息历史表,将5年以前毕业的学生数据转入历史表,历史表的建表语句如下:
sql
CREATE TABLE 学生基本信息历史表
(
学号 varchar(10),
姓名 varchar(50),
性别 varchar(2),
系所号 varchar(8),
是否有学籍 varchar(2)
);
其中两个表在"学号"和"系所号"上有索引。
(1)在系统运行一段时间后,发现如下语句执行速度缓慢:
sql
SELECT 学号, 姓名, 性别 FROM 学生基本信息表 WHERE 系所号 = '001'
UNION
SELECT 学号, 姓名, 性别 FROM 学生基本信息历史表 WHERE 系所号 = '001'
(2)在解决了前一个问题后,又发现如下2个语句速度缓慢:
sql
SELECT 学号, 姓名, 性别, 系所号 FROM 学生基本信息历史表 WHERE 姓名 LIKE '张%';
SELECT 学号, 姓名, 性别, 系所号 FROM 学生基本信息历史表 WHERE 姓名 LIKE '%云%';
管理员考虑在学生基本信息历史表的"姓名"字段建立索引以提高查询效率。
- 在情况(1)中,语句速度缓慢的主要原因是"系所号"列筛选操作的速度慢。 ×
语句速度缓慢的主要原因是UNION操作- 在情况(1)中,可以将union操作改为union all操作以提高语句执行效率。 √
UNION会对两个结果集进行去重操作,UNION ALL只是简单地将两个结果集合并起来,不进行去重操作,减少了不必要的处理开销。- 在情况(2)中,两条SQL语句速度缓慢的主要原因是数据量大,仅通过建立索引无法解决问题。 ×
通过建立索引可以提高第一条语句的查询效率- 在情况(2)中,在"姓名"列上建立索引可以提高第一个查询语句的执行效率。 √
- 在情况(2)中,在"姓名"列上建立索引可以提高第二个查询语句的执行效率。 ×
模糊匹配的通配符在开头,在这种情况下,数据库无法利用索引快速定位数据。
真考题库试卷5
某学校图书管理系统使用SQL Server作为数据库管理系统,在该系统中,保存了能够借书的所有人员信息。能够借书的人员信息主要来自于学校的教务系统的学生学籍数据以及人事系统的教师数据。考虑到学生学籍数据以及教师数据会经常变化,需要两个系统中的数据同步到图书管理系统中。教师数据和学生学籍数据总计约5万条。
为了实现自动数据同步,图书管理系统新上线了一数据同步程序。在同步程序上线后,数据库管理员发现每天数据备份量大幅度增加,尤其是数据库日志大幅度增加。经核查,该数据同步程序操作为每小时将所有从教务和人事系统中同步的数据删除,而后将数据重新插入。现需要对同步程序进行优化,某工程师提出了两套方案:
① 在教务和人事系统相关表中新增触发器,提取新增数据到增量数据表,同步程序每小时将增量数据表中数据同步至图书管理系统中。
② 在图书管理系统中新增与教务和人事系统结构相同的表,同步程序每小时将教务和人事的数据传输到图书管理系统对应表中,在图书管理系统数据库中使用SQL语句对比图书管理系统数据,获取增量后修改图书管理系统数据。
- 方案①对教务和人事系统的修改较大。 √
- 方案①对图书管理系统性能影响较大。 ×
- 方案①比方案②提取增量数据效率低。 ×
- 方案②中,对图书管理系统的性能可能造成一定的影响。 √
- 方案②比方案①协调和实施复杂度低。 √
真考题库试卷6
某学校网络计费系统使用SQL Server 2008数据库管理系统,系统中有登录日志表,建表语句如下:
sql
CREATE TABLE 登录日志表 (
序列号 int identity(1,1),
帐号 varchar(8),
登录时间 datetime,
退出时间 datetime,
本次上网费用 real
);
系统运行一段时间后,表中有近5千万条数据。
用户按登录时间查询近期上网情况时速度缓慢。某工程师建议对此表进行分区。解决该问题3年后,管理员考虑升级硬件,监控系统资源使用情况如下:
CPU使用率一般不超过50%;
内存使用率90%;
磁盘I/O使用率高峰期90%-95%,主要为读操作;
工程师给出两种硬件配置升级方案:
配置一:2颗处理器、6核心、主频2.4GHz;64GB内存;300GB 10K转SAS硬盘,3块,RAID0
配置二:2颗处理器、6核心、主频1.9GHz;128GB内存;800GB固态硬盘 SAS 读取密集型 MLC,2块,RAID1
- 工程师建议对登录日志表按登录时间分区不合理,因为分区不能有效提高查询效率。 ×
利用分区裁剪缩小了数据范围- 对登录日志表在登录时间列上以月为单位创建右侧分区函数,将表分成12个分区是最优方案,可有效提高查询效率。 √
- 从系统资源使用数据看,CPU使用率不超50%,说明CPU性能过剩,无需关注。 ×
随着业务的发展和数据量的进一步增加,CPU的负载可能会上升。需要考虑系统的未来扩展性以及其他可能影响CPU使用的因素- 内存使用率90%,磁盘|/O使用率高峰期90%-95%,配置二更合理,因其内存大且磁盘读性能好。 √
- 配置一的RAID0比配置二的RAID1写效率高,所以配置一在整体上更能满足系统需求。 ×
- 系统变慢时,内存使用率95%,表明内存是影响系统性能的关键因素,更换硬件时应着重提高内存性能。√
内存使用率达95%,说明内存资源紧张,很可能是影响系统性能的关键因素,更换硬件时着重提升内存性能是合理的- 磁盘I/O使用率高峰期高且主要为读操作,更换硬件时应在经济条件允许下采用RAID10磁盘阵列改善。 √
RAID10是RAID1+0,读写性能以及可靠性都比较高- 因为系统软件未调整,所以即便更换硬件也无法解决系统变慢问题。
从资源使用数据看,硬件性能不足(磁盘 I/O 使用率)是系统变慢的明显原因,更换合适硬件可改善性:能,并非仅靠软件调整
某高校基于SQL Server 2008构建了学生进出校备案系统,其中"申报情况表"的建表语句如下:
sql
CREATE TABLE 申报情况表(
ID varchar(8),
学工号 varchar(20),
申报日期 date,
去往地点 varchar(100),
出校日期 date,
返校日期 date
);
真考题库试卷7
系统运行一段时间后,此表已积累了近两百万条数据。目前系统在数据库中执行以下SQL语句时效率较低:
sql
SELECT 学工号, 申报日期
FROM 申报情况表
WHERE 出校日期 >= dateadd(day, -1, getdate());
- 为提高该查询效率,在'申报情况表"的"出校日期"列上建立索引可以显著提升查询速度。 √
WHERE 范围条件加索引可缩小范围- 在"申报情况表"的"学工号"列上建立索引对提高当前查询效率有明显帮助。 ×
在SELECT 后面的普通字段加索引基本没用- 若将查询语句中的条件出校日期>=dateadd(day.-1.getdate())"改为"申报日期>=dateadd(day.-1,getdate())",则应在"申报日期"列上建立索引来提高查询效率。 √
- 随着系统使用,数据量不断增加,考虑对"申报情况表"进行分区。甲工程师建议按"出校日期"分区,乙工程师建议按"学工号"分区,甲工程师的建议更能满足当前查询需求。 √
按"出校日期"分区,便于WHERE范围条件查找- 假设系统中还有其他与学生进出校相关的查询操作,如经常需要查询某个学工号的学生在特定时间段内的进出校记录,那么按"学工号"进行分区也具有一定的合理性。 √
真考题库试卷8
在系统运行半年后,此表中有近两百万条数据。该系统需在数据库中执行如下SQL语句:
sql
SELECT 学工号, 申报日期 FROM 申报情况表
WHERE 出校日期 >= dateadd(day, -1, getdate()) AND 去往地点 like '%医院%'
随着系统使用时间的增长,现需要考虑对该表进行分区,以保证后期该SQL语句效率。两位工程师给出了如下建议:
- 甲工程师认为应根据"出校日期"字段做分区。
- 乙工程师认为应根据"去往地点"字段做分区。
- 在不改变SQL语句和不对表做分区的情况下,在"出校日期"和"去往地点"列建立联合索引可以提高该查询效率。 √
- 对于学生进出校备案系统,在"申报情况表"的"去往地点"列上建立索引能显著提高给定查询语句的效率。 ×
模糊匹配的通配符在开头,在这种情况下,数据库无法利用索引快速定位数据。- 如果按照乙工程师的建议根据"去往地点"字段对"申报情况表"进行分区,在查询某一特定出校日期范围内的数据时,效率会比按"出校日期"分区高。 ×
根据"去往地点"字段分区会扫描更多的分区- 在学生进出校备案系统中,对"申报情况表"按"出校日期"分区后,不需要再对"出校日期"字段建立索引来提高查询效率了。 √
按"出校日期"分区再按"出校日期"分区对于提高查询效率的作用不大,反而会增加维护索引的开销
真考题库试卷9
在系统运行半年后,此表中有近两百万条数据。该系统需在数据库中执行如下SQL语句:
sql
SELECT 学工号, 申报日期
FROM 申报情况表
WHERE 出校日期 >= dateadd(day,-1,getdate()) AND 学工号 = '202201111';
为提高此查询的执行效率,在不改变SQL语句的情况下,采取了一些优化措施。同时,随着系统运行时间增长,系统运行速度逐渐变慢,经分析为磁盘I/O不能满足数据库系统频繁读写的要求,工程师建议增加一块相同磁盘,将两块磁盘调整为RAID1模式。
- 在"申报情况表"中的"申报日期"列上建立索引对提高该查询效率无帮助。 √
在SELECT 后面的普通字段加索引基本没用- 将两块磁盘调整为RAID1模式,写操作性能会提升。 ×
RAID1模式是磁盘镜像模式,即两块磁盘中数据完全相同,写入数据时需要同时写:入两块磁盘。这会增加写操作的时间开销,导:致写操作性能下降- 将两块磁盘调整为RAID1模式,读操作性能会提升。 √
RAID1模式下,两块磁盘存储相同的数据。在进行读操作时,可以从任意一块磁盘读取数据,这样在一定程度上可以并行读取,提高了读操作的性能。
真考题库试卷10
某高校教务管理系统存储了近20年学生的成绩信息,在校生约3万人。该系统使用SQL Server 2008数据库管理系统。为督促学生注重学习过程,学校要求各门课程进行过程化考核,每门课程总评成绩由若干分项成绩组成,任课教师只需输入分项成绩,系统自动计算总评成绩。
(1)为提高学生查询总评成绩的速度,开发人员提出在成绩表中增加"总评成绩"列,当教师输入分项成绩时,系统自动将计算出的总评成绩保存到成绩表中。
(2)教务管理系统的学生表中有"学号"列,字符型,长度为10,形如"2021111245",前四位表示入学年份,且已为该列建立索引。现要查询2021年入学的学生信息,开发人员给出两种查询方案:
sql
方案1:
SELECT * FROM 学生表 WHERE LEFT(学号, 4) = '2021'
方案2:
SELECT * FROM 学生表 WHERE 学号 >= '2021000000' AND 学号 <= '2021999999'
- 情况(1)中,在成绩表中增加"总评成绩"列能显著提高查询效率,且对系统维护和数据一致性影响不大。 ×
每次分项成绩的修改都要确保总评成绩的准确更新,如果在计算或更新过程中出现异常(如程序错误、数据传输问题等),可能会导致数据不一致的情况发生对系统维护和数据一致性影响较大- 情况(1)中,在成绩表中增加"总评成绩"列虽能提高查询效率,但会增加系统维护成本和数据不一致的风险。 √
- 情况(2)中,方案1执行效率更高,因为使用函数处理学号更直观。 ×
对列使用函数会使学号列上的索引失效,数据库需要对整个表进行扫描来获取满足条件的记录,隨着数据量的增加,查询效率会显著降低- 情况(2)中,方案2执行效率更高,因为能充分利用学号列上的索引。 √
- 情况(5)中,若后续查询主要基于入学年份进行筛选,方案1更具优势。 √
真考题库试卷12
某商场商品经营管理系统使用SQL Server 2008数据库管理系统,此系统上线运行5年后,业务人员使用系统时发现速度很慢,技术人员分析后发现系统缓慢的原因为其销售明细表数据量过大,导致性能整体下降。已知此系统的销售明细表建表语句如下:
sql
CREATE TABLE 销售明细(
序列号 int IDENTITY(1,1) NOT NULL,
商品号 int NOT NULL,
销售日期 date NULL,
销售数量 int NOT NULL,
销售价格 int NOT NULL
);
常用业务一般只访问此表中近3个月的数据,且大部分查询均与日期相关,数据统计时所涉及的数据不超过3年。
为了提高系统性能,某技术人员对此表进行了分区。在分区实施后,经与业务人员协商,计划建立销售明细历史表,将销售明细表中3年前的数据转入历史表中。已知历史表的结构与销售明细表结构完全相同(包括分区及相关索引等),但是将3年前数据转入历史表时发现操作性能较差。
- 销售明细表数据查询与日期相关,可以考虑使用"销售日期"列作为分区列。 √
- 销售明细表数据查询一般只使用最近3个月的数据,可以考虑使用序列号作为分区列。 ×
使用序列号作为分区列无法实现"快速定位近3个月数据"以及"3年前数据"的需求- 数据转入历史表时,如果采用禁用索引的方案后期还需要重建索引,整体效率未必提高。 ×
若不禁用索引,迁移过程中每插入一条数据,需同步更新索引(多次I/O操作),效率极低;禁用索引后,迁移仅需写入数据(无索引维护开销)- 使用分区切换(SWITCH PARTITION)方法可以大幅度提高数据转入历史表的速度。 √
传统数据迁移(如"INSERT...SELECT")需逐行复制数据,涉及大量I/O与计算开销;而"分区切换"是通过"修改元数据指针"实现分区数据转移,不涉及实际数据复制- 建立了销售历史表后,如需查询某一商品的全部销售记录,则需要查询销售明细表和其历史表,查询效率会比不转入历史表有大幅度下降。 ×
查询"全部销售记录"需关联销售表(近3年数据)与历史表(3年前数据),关联查询的总开销通常低于单表查询大量数据的开销
真考题库试卷13
设某超市经营管理系统使用SQL Server 2008数据库管理系统,为了保证数据库可靠运行,数据库管理员设置了每天夜间对数据库进行一次完整备份,备份数据保留2个月的备份策略。上线运行1年后,SQL Server数据库中数据已经达到近200GB。每天夜间要运行6个小时才能完成数据库的一次完整备份,影响了夜间统计等业务正常运行。同时,备份空间也非常紧张。
为了解决备份问题,某工程师提出如下备份方案:
①每星期进行一次完整备份,每天进行一次差异备份,每6个小时进行一次日志备份,相关数据保留2个月。
②为了保证数据库可靠运行,数据库管理员计划在另一城市建立备用数据库,考虑采用SQL Server数据库镜像技术实现数据同步。
- 从备份速度上看,由于引入了差异和日志备份,新方案比原有方案速度快。 √
差异备份仅复制自上次完整备份后变化的数据(通常远小于200GB);日志备份仅复制事务日志中新增的记录(体积更小,速度更:快)。新方案中除每周一次完整备份外,其余:备份(差异、日志)的体积和耗时均远低于完整备份,整体备份速度显奢提升。- 从每日的完整备份变为完整备份加差异备份和日志备份会导致备份空间增加。 ×
差异备份和日志备份的总空间远小于频繁的完整备份,因此备份空间会减少而非增加。- 从每日的完整备份变为完整备份加差异备份和日志备份会降低在数据库完全损坏时的恢复时间。 √
数据库完全损坏时的恢复流程:原有方案:仅需恢复"最近一次完整备份",步骤简单,耗时较短。新方案:需先恢复"最近一次完整备份",再恢复"最后一次差异备份",最后恢复"差异备份之后的所有日志备份",步骤更多,恢复链条更长,总耗时通常增加。- 备用数据库采用SQL Server数据库镜像技术实现数据同步方案基本可行。 √
- 为了保证数据一致性,数据库镜像中应使用同步模式。×
"保证可靠运行"(灾难恢复),异步模式已能满足大多数场景的一致性需求(数据差极小),且避免主库性能下降。
真考题库试卷15
某网上商城因业务发展,采用了新的经营管理系统,该系统使用SQL Server 2008数据库管理系统。新系统上线前,需将原系统(使用SQL Server 2000,数据结构与新系统不完全一致)的数据导入新系统,且为保证数据一致性,数据导入时需暂停业务并在3小时内完成。
在数据导入过程中,出现了以下情况和不同观点:
(1)实施人员发现原有数据量很大,导入需4小时,业务无法接受。经分析,某工程师认为数据导入时数据库I/O很高,但导入程序本身对系统资源占用率低,建议将数据恢复模式从"完整"模式改为"简单"模式以提高导入速度;另一位工程师则认为此方法未必能提高速度,且可能导致数据丢失,不建议使用。
- 将数据恢复模式从"完整"模式改为"简单"模式一定能提高数据导入速度。 ×
在一般情况下可以减少日志开销,理论上可能提高数据导入速度,但不能绝对地说一定- 因为数据导入过程中仅修改恢复模式,所以不存在数据丢失风险。 ×
由于"简单"模式下日志记录不完整,可能无法完整地恢复到数据导入前的状态,从而导致数据丢失- 若数据导入过程中数据库|/O很高是导致导入时间长的主要原因,那么修改恢复模式(从"完整"模式改为"简单"模式)有可能提高数据导入速度。 √
- 只要在数据导入结束后将恢复模式改回"完整"模式,就可以完全避免因修改恢复模式带来的潜在风险。 ×
- 由于数据导入程序对系统资源占用率低,所以修改恢复模式是解决数据导入速度问题的唯一有效方法。 ×
还可以考虑优化数据导入程序、增加硬件资源(如提高磁盘I/O性能、增加内存等)、对数据进行预处理等多种方式来提高数据导入速度