当前位置:首页 » 编程语言 » sql查询慢如何建立索引
扩展阅读
webinf下怎么引入js 2023-08-31 21:54:13
堡垒机怎么打开web 2023-08-31 21:54:11

sql查询慢如何建立索引

发布时间: 2022-12-15 18:09:14

sql怎么建立索引

什么是索引
拿汉语字典的目录页(索引)打比方:正如汉语字典中的汉字按页存放一样,SQL Server中的数据记录也是按页存放的,每页容量一般为4K 。为了加快查找的速度,汉语字(词)典一般都有按拼音、笔画、偏旁部首等排序的目录(索引),我们可以选择按拼音或笔画查找方式,快速查找到需要的字(词)。
同理,SQL Server允许用户在表中创建索引,指定按某列预先排序,从而大大提高查询速度。
• SQL Server中的数据也是按页( 4KB )存放
• 索引:是SQL Server编排数据的内部方法。它为SQL Server提供一种方法来编排查询数据。
• 索引页:数据库存储索引的数据页;索引页类似于汉语字(词)典中按拼音或笔画排序的目录页。
• 索引的作用:通过使用索引,可以大大提高数据库的检索速度,改善数据库性能。

索引类型
• 唯一索引:唯一索引不允许两行具有相同的索引值
• 主键索引:为表定义一个主键将自动创建主键索引,主键索引是唯一索引的特殊类型。主键索引要求主键中的每个值是唯一的,并且不能为空
• 聚集索引(Clustered):表中各行的物理顺序与键值的逻辑(索引)顺序相同,每个表只能有一个
• 非聚集索引(Non-clustered):非聚集索引指定表的逻辑顺序。数据存储在一个位置,索引存储在另一个位置,索引中包含指向数据存储位置的指针。可以有多个,小于249个

索引类型:再次用汉语字典打比方,希望大家能够明白聚集索引和非聚集索引这两个概念。

唯一索引:
唯一索引不允许两行具有相同的索引值。
如果现有数据中存在重复的键值,则大多数数据库都不允许将新创建的唯一索引与表一起保存。当新数据将使表中的键值重复时,数据库也拒绝接受此数据。例如,如果在stuInfo表中的学员员身份证号(stuID) 列上创建了唯一索引,则所有学员的身份证号不能重复。
提示:创建了唯一约束,将自动创建唯一索引。尽管唯一索引有助于找到信息,但为了获得最佳性能,建议使用主键约束或唯一约束。

主键索引:
在数据库关系图中为表定义一个主键将自动创建主键索引,主键索引是唯一索引的特殊类型。主键索引要求主键中的每个值是唯一的。当在查询中使用主键索引时,它还允许快速访问数据。

聚集索引(clustered index)
在聚集索引中,表中各行的物理顺序与键值的逻辑(索引)顺序相同。表只能包含一个聚集索引。例如:汉语字(词)典默认按拼音排序编排字典中的每页页码。拼音字母a,b,c,d……x,y,z就是索引的逻辑顺序,而页码1,2,3……就是物理顺序。默认按拼音排序的字典,其索引顺序和逻辑顺序是一致的。即拼音顺序较后的字(词)对应的页码也较大。如拼音“ha”对应的字(词)页码就比拼音“ba” 对应的字(词)页码靠后。

非聚集索引(Non-clustered)
如果不是聚集索引,表中各行的物理顺序与键值的逻辑顺序不匹配。聚集索引比非聚集索引(nonclustered index)有更快的数据访问速度。例如,按笔画排序的索引就是非聚集索引,“1”画的字(词)对应的页码可能比“3”画的字(词)对应的页码大(靠后)。
提示:SQL Server中,一个表只能创建1个聚集索引,多个非聚集索引。设置某列为主键,该列就默认为聚集索引

如何创建索引
使用T-SQL语句创建索引的语法:
CREATE [UNIQUE] [CLUSTERED|NONCLUSTERED]
INDEX index_name
ON table_name (column_name…)
[WITH FILLFACTOR=x]
q UNIQUE表示唯一索引,可选
q CLUSTERED、NONCLUSTERED表示聚集索引还是非聚集索引,可选
q FILLFACTOR表示填充因子,指定一个0到100之间的值,该值指示索引页填满的空间所占的百分比

在stuMarks表的writtenExam列创建索引:
USE stuDB
GO
IF EXISTS (SELECT name FROM sysindexes
WHERE name = 'IX_writtenExam')
DROP INDEX stuMarks.IX_writtenExam
/*--笔试列创建非聚集索引:填充因子为30%--*/
CREATE NONCLUSTERED INDEX IX_writtenExam
ON stuMarks(writtenExam)
WITH FILLFACTOR= 30
GO
/*-----指定按索引 IX_writtenExam 查询----*/
SELECT * FROM stuMarks (INDEX=IX_writtenExam)
WHERE writtenExam BETWEEN 60 AND 90
虽然我们可以指定SQL Server按哪个索引进行数据查询,但一般不需要我们人工指定。SQL Server将会根据我们创建的索引,自动优化查询。

索引的优缺点
• 优点
– 加快访问速度
– 加强行的唯一性
• 缺点
– 带索引的表在数据库中需要更多的存储空间
– 操纵数据的命令需要更长的处理时间,因为它们需要对索引进行更新

创建索引的指导原则
• 请按照下列标准选择建立索引的列。
– 该列用于频繁搜索
– 该列用于对数据进行排序
• 请不要使用下面的列创建索引:
– 列中仅包含几个不同的值。
– 表中仅包含几行。为小型表创建索引可能不太划算,因为SQL Server在索引中搜索数据所花的时间比在表中逐行搜索所花的时间更长

⑵ SQL表字段如何建立索引难道就是添加SQL查询语句

不是添加SQL查询语句,而是添加创建索引的语句,例如:
1、创建主键索引
alter
table
table_name
add
constraint
index_name
primary
key
(col1);
2、创建唯一键索引
create
unique
index
uk_name
on
table_name
(col2);
3、创建普通索引
create
index
index_name
on
table_name
(col3);

⑶ 如何解决SQL Server查询速度缓慢的问题

优化SQL Server查询速度的方法:

1、把数据、日志、索引放到不同的I/O设备上,增加读取速度,以前可以将Tempdb应放在RAID0上,SQL2000不在支持。数据量(尺寸)越大,提高I/O越重要.

2、纵向、横向分割表,减少表的尺寸(sp_spaceuse)

3、升级硬件

4、根据查询条件,建立索引,优化索引、优化访问方式,限制结果集的数据量。注意填充因子要适当(最好是使用默认值0)。索引应该尽量小,使用字节数小的列建索引好(参照索引的创建),不要对有限的几个值的字段建单一索引如性别字段

5、提高网速;

6、扩大服务器的内存,Windows 2000和SQL server 2000能支持4-8G的内存。

配置虚拟内存:虚拟内存大小应基于计算机上并发运行的服务进行配置。运行 Microsoft SQL Server? 2000 时,可考虑将虚拟内存大小设置为计算机中安装的物理内存的 1.5 倍。如果另外安装了全文检索功能,并打算运行 Microsoft 搜索服务以便执行全文索引和查询,可考虑:将虚拟内存大小配置为至少是计算机中安装的物理内存的 3 倍。将 SQL Server max server memory 服务器配置选项配置为物理内存的 1.5 倍(虚拟内存大小设置的一半)。

7、增加服务器CPU个数;但是必须明白并行处理串行处理更需要资源例如内存。使用并行还是串行程是MsSQL自动评估选择的。单个任务分解成多个任务,就可以在处理器上运行。例如耽搁查询的排序、连接、扫描和GROUP BY字句同时执行,SQL SERVER根据系统的负载情况决定最优的并行等级,复杂的需要消耗大量的CPU的查询最适合并行处理。但是更新操作UPDATE,INSERT, DELETE还不能并行处理。

8、如果是使用like进行查询的话,简单的使用index是不行的,但是全文索引,耗空间。 like ''a%'' 使用索引 like ''%a'' 不使用索引用 like ''%a%'' 查询时,查询耗时和字段值总长度成正比,所以不能用CHAR类型,而是VARCHAR。对于字段的值很长的建全文索引。

9、DB Server 和APPLication Server 分离;OLTP和OLAP分离

10、分布式分区视图可用于实现数据库服务器联合体。

联合体是一组分开管理的服务器,但它们相互协作分担系统的处理负荷。这种通过分区数据形成数据库服务器联合体的机制能够扩大一组服务器,以支持大型的多层 Web 站点的处理需要。有关更多信息,参见设计联合数据库服务器。(参照SQL帮助文件''分区视图'')

a、在实现分区视图之前,必须先水平分区表

b、在创建成员表后,在每个成员服务器上定义一个分布式分区视图,并且每个视图具有相同的名称。这样,引用分布式分区视图名的查询可以在任何一个成员服务器上运行。系统操作如同每个成员服务器上都有一个原始表的复本一样,但其实每个服务器上只有一个成员表和一个分布式分区视图。数据的位置对应用程序是透明的。

11、重建索引 DBCC REINDEX ,DBCC INDEXDEFRAG,收缩数据和日志 DBCC SHRINKDB,DBCC SHRINKFILE.设置自动收缩日志.对于大的数据库不要设置数据库自动增长,它会降低服务器的性能。

在T-sql的写法上有很大的讲究,下面列出常见的要点:首先,DBMS处理查询计划的过程是这样的:

1、查询语句的词法、语法检查

2、将语句提交给DBMS的查询优化器

3、优化器做代数优化和存取路径的优化

4、由预编译模块生成查询规划

5、然后在合适的时间提交给系统处理执行

6、最后将执行结果返回给用户。

其次,看一下SQL SERVER的数据存放的结构:一个页面的大小为8K(8060)字节,8个页面为一个盘区,按照B树存放。

12、 Commit和rollback的区别 Rollback:回滚所有的事物。 Commit:提交当前的事物.没有必要在动态SQL里写事物,如果要写请写在外面如: begin tran exec(@s) commit trans 或者将动态SQL 写成函数或者存储过程。

13、在查询Select语句中用Where字句限制返回的行数,避免表扫描,如果返回不必要的数据,浪费了服务器的I/O资源,加重了网络的负担降低性能。如果表很大,在表扫描的期间将表锁住,禁止其他的联接访问表,后果严重。

14、SQL的注释申明对执行没有任何影响

15、尽可能不使用光标,它占用大量的资源。如果需要row-by-row地执行,尽量采用非光标技术,如:在客户端循环,用临时表,Table变量,用子查询,用Case语句等等。游标可以按照它所支持的提取选项进行分类:只进必须按照从第一行到最后一行的顺序提取行。FETCH NEXT 是唯一允许的提取操作,也是默认方式。可滚动性可以在游标中任何地方随机提取任意行。游标的技术在SQL2000下变得功能很强大,他的目的是支持循环。有四个并发选项 READ_ONLY:不允许通过游标定位更新(Update),且在组成结果集的行中没有锁。 OPTIMISTIC WITH valueS:乐观并发控制是事务控制理论的一个标准部分。乐观并发控制用于这样的情形,即在打开游标及更新行的间隔中,只有很小的机会让第二个用户更新某一行。当某个游标以此选项打开时,没有锁控制其中的行,这将有助于最大化其处理能力。如果用户试图修改某一行,则此行的当前值会与最后一次提取此行时获取的值进行比较。如果任何值发生改变,则服务器就会知道其他人已更新了此行,并会返回一个错误。如果值是一样的,服务器就执行修改。选择这个并发选项?OPTIMISTIC WITH ROW VERSIONING:此乐观并发控制选项基于行版本控制。使用行版本控制,其中的表必须具有某种版本标识符,服务器可用它来确定该行在读入游标后是否有所更改。在 SQL Server 中,这个性能由 timestamp 数据类型提供,它是一个二进制数字,表示数据库中更改的相对顺序。每个数据库都有一个全局当前时间戳值:@@DBTS。每次以任何方式更改带有 timestamp 列的行时,SQL Server 先在时间戳列中存储当前的 @@DBTS 值,然后增加 @@DBTS 的值。如果某个表具有 timestamp 列,则时间戳会被记到行级。服务器就可以比较某行的当前时间戳值和上次提取时所存储的时间戳值,从而确定该行是否已更新。服务器不必比较所有列的值,只需比较 timestamp 列即可。如果应用程序对没有 timestamp 列的表要求基于行版本控制的乐观并发,则游标默认为基于数值的乐观并发控制。 SCROLL LOCKS 这个选项实现悲观并发控制。在悲观并发控制中,在把数据库的行读入游标结果集时,应用程序将试图锁定数据库行。在使用服务器游标时,将行读入游标时会在其上放置一个更新锁。如果在事务内打开游标,则该事务更新锁将一直保持到事务被提交或回滚;当提取下一行时,将除去游标锁。如果在事务外打开游标,则提取下一行时,锁就被丢弃。因此,每当用户需要完全的悲观并发控制时,游标都应在事务内打开。更新锁将阻止任何其它任务获取更新锁或排它锁,从而阻止其它任务更新该行。然而,更新锁并不阻止共享锁,所以它不会阻止其它任务读取行,除非第二个任务也在要求带更新锁的读取。滚动锁根据在游标定义的 SELECT 语句中指定的锁提示,这些游标并发选项可以生成滚动锁。滚动锁在提取时在每行上获取,并保持到下次提取或者游标关闭,以先发生者为准。下次提取时,服务器为新提取中的行获取滚动锁,并释放上次提取中行的滚动锁。滚动锁独立于事务锁,并可以保持到一个提交或回滚操作之后。如果提交时关闭游标的选项为关,则 COMMIT 语句并不关闭任何打开的游标,而且滚动锁被保留到提交之后,以维护对所提取数据的隔离。所获取滚动锁的类型取决于游标并发选项和游标 SELECT 语句中的锁提示。

16、用Profiler来跟踪查询,得到查询所需的时间,找出SQL的问题所在;用索引优化器优化索引

17、注意UNion和UNion all 的区别。UNION all好

18、注意使用DISTINCT,在没有必要时不要用,它同UNION一样会使查询变慢。重复的记录在查询里是没有问题的

19、查询时不要返回不需要的行、列

20、用sp_configure ''query governor cost limit''或者SET QUERY_GOVERNOR_COST_LIMIT来限制查询消耗的资源。当评估查询消耗的资源超出限制时,服务器自动取消查询,在查询之前就扼杀掉。 SET LOCKTIME设置锁的时间

21、用select top 100 / 10 Percent 来限制用户返回的行数或者SET ROWCOUNT来限制操作的行

22、在SQL2000以前,一般不要用如下的字句

", "!=", "!>", "!<", "NOT", "NOT EXISTS", "NOT IN", "NOT LIKE", and "LIKE ''%500''",因为他们不走索引全是表扫描。也不要在WHere字句中的列名加函数,如Convert,substring等,如果必须用函数的时候,创建计算列再创建索引来替代.还可以变通写法:WHERE SUBSTRING(firstname,1,1)= ''m''改为WHERE firstname like ''m%''(索引扫描),一定要将函数和列名分开。并且索引不能建得太多和太大。NOT IN会多次扫描表,使用EXISTS、NOT EXISTS ,IN , LEFT OUTER JOIN 来替代,特别是左连接,而Exists比IN更快,最慢的是NOT操作.如果列的值含有空,以前它的索引不起作用,现在2000的优化器能够处理了。相同的是IS NULL,“NOT", "NOT EXISTS", "NOT IN"能优化她,而”<>”等还是不能优化,用不到索引。

23、使用Query Analyzer,查看SQL语句的查询计划和评估分析是否是优化的SQL。一般的20%的代码占据了80%的资源,我们优化的重点是这些慢的地方。

24、如果使用了IN或者OR等时发现查询没有走索引,使用显示申明指定索引: SELECT * FROM PersonMember (INDEX = IX_Title) WHERE processid IN (‘男’,‘女’)

25、将需要查询的结果预先计算好放在表中,查询的时候再SELECT。这在SQL7.0以前是最重要的手段。例如医院的住院费计算。

26、MIN()和 MAX()能使用到合适的索引。

27、数据库有一个原则是代码离数据越近越好,所以优先选择Default,依次为Rules,Triggers, Constraint(约束如外健主健CheckUNIQUE……,数据类型的最大长度等等都是约束),Procere.这样不仅维护工作小,编写程序质量高,并且执行的速度快。

28、如果要插入大的二进制值到Image列,使用存储过程,千万不要用内嵌INsert来插入(不知JAVA 是否)。因为这样应用程序首先将二进制值转换成字符串(尺寸是它的两倍),服务器受到字符后又将他转换成二进制值.存储过程就没有这些动作:方法:Create procere p_insert as insert into table(Fimage) values (@image),在前台调用这个存储过程传入二进制参数,这样处理速度明显改善。

⑷ Mysql 查询速度慢怎么办

问题

我们有一个 SQL,用于找到没有主键 / 唯一键的表,但是在 MySQL 5.7 上运行特别慢,怎么办?


实验

我们搭建一个 MySQL 5.7 的环境,此处省略搭建步骤。

写个简单的脚本,制造一批带主键和不带主键的表:

可以看到执行时间变成了 0.67s。

整理

我们诊断的关键点如下:

1. 对于 information_schema 中的元数据表,执行计划不能提供有效信息。

2. 通过查看 MySQL 改写后的 SQL,我们猜测了优化器发生了误判。

3. 我们增加了 hint,指导 MySQL 正确进行优化判断。

但目前我们的实验仅限于猜测,猜中了万事大吉,猜不中就无法做出好的诊断。

⑸ 如何优化sql语句,怎么加索引

1、主键就是聚集索引2、只要建立索引就能显着提高查询速度3、把所有需要提高查询速度的字段都加进聚集索引,以提高查询速度(四)其他书上没有的索引使用经验总结1、用聚合索引比用不是聚合索引的主键速度快2、用聚合索引比用一般的主键作orderby时速度快,特别是在小数据量情况下3、使用聚合索引内的时间段,搜索时间会按数据占整个数据表的百分比成比例减少,而无论聚合索引使用了多少个4、日期列不会因为有分秒的输入而减慢查询速度(五)其他注意事项1.不要索引常用的小型表2.不要把社会保障号码(SSN)或身份证号码(ID)选作键3.不要用用户的键4.不要索引memo/notes字段和不要索引大型文本字段(许多字符)5.使用系统生成的主键二、改善SQL语句1、Like语句是否属于SARG取决于所使用的通配符的类型2、or会引起全表扫描3、非操作符、函数引起的不满足SARG形式的语句4、IN的作用相当与OR5、尽量少用NOT6、exists和in的执行效率是一样的7、用函数charindex()和前面加通配符%的LIKE执行效率一样8、union并不绝对比or的执行效率高9、字段提取要按照“需多少、提多少”的原则,避免“select*”10、count(*)不比count(字段)慢11、orderby按聚集索引列排序效率最高12、高效的TOP

⑹ sql怎么建立索引

进入查询窗口后,输入下面的语句:x0dx0ax0dx0aCREATE INDEX mycolumn_index ON mytable (myclumn)x0dx0ax0dx0a这个语句建立了一个名为mycolumn_index的索引。你可以给一个索引起任何名字,但你应该在索引名中包含所索引的字段名,这对你将来弄清楚建立该索引的意图是有帮助的。x0dx0ax0dx0a注意:x0dx0ax0dx0a在本书中你执行任何SQL语句,都会收到如下的信息:x0dx0ax0dx0aThis command did not return data,and it did not return any rowsx0dx0ax0dx0a这说明该语句执行成功了。x0dx0ax0dx0a索引mycolumn_index对表mytable的mycolumn字段进行。这是个非聚簇索引,也是个非唯一索引。(这是一个索引的缺省属性)x0dx0ax0dx0a如果你需要改变一个索引的类型,你必须删除原来的索引并重建 一个。建立了一个索引后,你可以用下面的SQL语句删除它:x0dx0ax0dx0aDROP INDEX mytable.mycolumn_indexx0dx0ax0dx0a注意在DROP INDEX 语句中你要包含表的名字。在这个例子中,你删除的索引是mycolumn_index,它是表mytable的索引。x0dx0ax0dx0a要建立一个聚簇索引,可以使用关键字CLUSTERED。)记住一个表只能有一个聚簇索引。(这里有一个如何对一个表建立聚簇索引的例子:x0dx0ax0dx0aCREATE CLUSTERED INDEX mycolumn_clust_index ON mytable(mycolumn)x0dx0ax0dx0a如果表中有重复的记录,当你试图用这个语句建立索引时,会出现错误。但是有重复记录的表也可以建立索引;你只要使用关键字ALLOW_DUP_ROW把这一点告诉SQL Sever即可:x0dx0ax0dx0aCREATE CLUSTERED INDEX mycolumn_cindex ON mytable(mycolumn)x0dx0ax0dx0aWITH ALLOW_DUP_ROWx0dx0ax0dx0a这个语句建立了一个允许重复记录的聚簇索引。你应该尽量避免在一个表中出现重复记录,但是,如果已经出现了,你可以使用这种方法。x0dx0ax0dx0a要对一个表建立唯一索引,可以使用关键字UNIQUE。对聚簇索引和非聚簇索引都可以使用这个关键字。这里有一个例子:x0dx0ax0dx0aCREATE UNIQUE COUSTERED INDEX myclumn_cindex ON mytable(mycolumn)x0dx0ax0dx0a这是你将经常使用的索引建立语句。无论何时,只要可以,你应该尽量对一个对一个表建立唯一聚簇索引来增强查询操作。x0dx0ax0dx0a最后,要建立一个对多个字段的索引——复合索引——在索引建立语句中同时包含多个字段名。下面的例子对firstname和lastname两个字段建立索引:x0dx0ax0dx0aCREATE INDEX name_index ON username(firstname,lastname)x0dx0ax0dx0a这个例子对两个字段建立了单个索引。在一个复合索引中,你最多可以对16个字段进行索引。x0dx0ax0dx0a用事务管理器建立索引x0dx0ax0dx0a用事务管理器建立索引比用SQL语句容易的多。使用事务管理器,你可以看到已经建立的索引的列表,并可以通过图形界面选择索引选项。x0dx0ax0dx0a使用事务管理器你可以用两种方式建立索引:使用Manage Tables窗口或使用Manage Indexes窗口。x0dx0ax0dx0a要用Manage Tables 窗口建立一个新索引,单击按钮Advanced Options(它看起来象一个前面有一加号的表)。这样就打开了Advanced Options对话框。这个对话框有一部分标名为Primary Key(见图11.1)。x0dx0ax0dx0a图11。1x0dx0ax0dx0a要建立一个新索引,从下拉列表中选择你想对之建立索引的字段名。如果你想建立一个对多字段的索引,你可以选择多个字段名。你还可以选择索引是聚簇的还是非聚簇的。在保存表信息后,索引会自动被建立。在Manage Tables窗口中的字段名旁边,会出现一把钥匙。x0dx0ax0dx0a你已经为你的表建立了“主索引”。主索引必须对不包含空值的字段建立。另外,主索引强制一个字段成为唯一值字段。x0dx0ax0dx0a要建立没有这些限制的索引,你需要使用Manage Indexes窗口。从菜单中选择Manage|Indexes,打开Manage Indexes 窗口。在Manage Indexes 窗口中,你可以通过下拉框选择表和特定的索引。(见图11.2)。要建立一个新索引,从Index下拉框中选择New Index.,然后就可以选择要对之建立索引的字段。单击按钮Add,把字段加人到索引中。x0dx0ax0dx0a图11。2x0dx0ax0dx0a你可以为你的索引选择许多不同的选项。例如,你可以选择该索引是聚簇的还是非聚簇的。你还可以指定该索引为唯一索引。设计好索引后,单击按钮Build,建立该索引。x0dx0ax0dx0a注意:x0dx0ax0dx0a唯一索引是指该字段不能有重复的值,而不是只能建立这一个索引。x0dx0ax0dx0aSQL核心语句x0dx0ax0dx0a在第十章,你学会了如何用SQL SELECT 语句从一个表中取数据。但是,到现在为止,还没有讨论如何添加,修改或删除表中的数据。在这一节中,你将学习这些内容。x0dx0ax0dx0a插入数据x0dx0ax0dx0a向表中添加一个新记录,你要使用SQL INSERT 语句。这里有一个如何使用这种语句的例子:x0dx0ax0dx0aINSERT mytable (mycolumn) VALUES (‘some data')x0dx0ax0dx0a这个语句把字符串'some data'插入表mytable的mycolumn字段中。将要被插入数据的字段的名字在第一个括号中指定,实际的数据在第二个括号中给出。x0dx0ax0dx0aINSERT 语句的完整句法如下:x0dx0ax0dx0aINSERT [INTO] {table_name|view_name} [(column_list)] {DEFAULT VALUES |x0dx0ax0dx0aValues_list | select_statement}x0dx0ax0dx0a如果一个表有多个字段,通过把字段名和字段值用逗号隔开,你可以向所有的字段中插入数据。假设表mytable有三个字段first_column,second_column,和third_column。下面的INSERT语句添加了一条三个字段都有值的完整记录:x0dx0ax0dx0aINSERT mytable (first_column,second_column,third_column)x0dx0ax0dx0aVALUES (‘some data','some more data','yet more data')x0dx0ax0dx0a注意:x0dx0ax0dx0a你可以使用INSERT语句向文本型字段中插入数据。但是,如果你需要输入很长的字符串,你应该使用WRITETEXT语句。这部分内容对本书来说太高级了,因此不加讨论。要了解更多的信息,请参考Microsoft SQL Sever 的文档。x0dx0ax0dx0a如果你在INSERT 语句中只指定两个字段和数据会怎么样呢?换句话说,你向一个表中插入一条新记录,但有一个字段没有提供数据。在这种情况下,有下面的四种可能:x0dx0ax0dx0a如果该字段有一个缺省值,该值会被使用。例如,假设你插入新记录时没有给字段third_column提供数据,而这个字段有一个缺省值'some value'。在这种情况下,当新记录建立时会插入值'some value'。x0dx0a如果该字段可以接受空值,而且没有缺省值,则会被插入空值。x0dx0a如果该字段不能接受空值,而且没有缺省值,就会出现错误。你会收到错误信息:x0dx0aThe column in table mytable may not be null.x0dx0ax0dx0a最后,如果该字段是一个标识字段,那么它会自动产生一个新值。当你向一个有标识字段的表中插入新记录时,只要忽略该字段,标识字段会给自己赋一个新值。x0dx0a注意:x0dx0ax0dx0a向一个有标识字段的表中插入新记录后,你可以用SQL变量@@identity来访问新记录x0dx0ax0dx0a的标识字段的值。考虑如下的SQL语句:x0dx0ax0dx0aINSERT mytable (first_column) VALUES(‘some value')x0dx0ax0dx0aINSERT anothertable(another_first,another_second)x0dx0ax0dx0aVALUES(@@identity,'some value')x0dx0ax0dx0a如果表mytable有一个标识字段,该字段的值会被插入表anothertable的another_first字段。这是因为变量@@identity总是保存最后一次插入标识字段的值。x0dx0ax0dx0a字段another_first应该与字段first_column有相同的数据类型。但是,字段another_first不能是应该标识字段。Another_first字段用来保存字段first_column的值。x0dx0ax0dx0a删除记录x0dx0ax0dx0a要从表中删除一个或多个记录,需要使用SQL DELETE语句。你可以给DELETE 语句提供WHERE 子句。WHERE子句用来选择要删除的记录。例如,下面的这个DELETE语句只删除字段first_column的值等于'Delete Me'的记录:x0dx0ax0dx0aDELETE mytable WHERE first_column='Deltet Me'x0dx0ax0dx0aDELETE 语句的完整句法如下:x0dx0ax0dx0aDELETE [FROM] {table_name|view_name} [WHERE clause]x0dx0ax0dx0a在SQL SELECT 语句中可以使用的任何条件都可以在DELECT 语句的WHERE子句中使用。例如,下面的这个DELETE语句只删除那些first_column字段的值为'goodbye'或 second_column字段的值为 'so long'的记录:x0dx0ax0dx0aDELETE mytable WHERE first_column='goodbyOR second_column='so long'x0dx0ax0dx0a如果你不给DELETE 语句提供WHERE 子句,表中的所有记录都将被删除。你不应该有这种想法。如果你想删除应该表中的所有记录,应使用第十章所讲的TRUNCATE TABLE语句。x0dx0ax0dx0a注意:x0dx0ax0dx0a为什么要用TRUNCATE TABLE 语句代替DELETE语句?当你使用TRUNCATE TABLE语句时,记录的删除是不作记录的。也就是说,这意味着TRUNCATE TABLE 要比DELETE快得多

⑺ 如何解决SQL查询速度太慢

1. 执行计划中明明有使用到索引,为什么执行还是这么慢?

2. 执行计划中显示扫描行数为 644,为什么 slow log 中显示 100 多万行?
a. 我们先看执行计划,选择的索引 “INDX_BIOM_ELOCK_TASK3(TASK_ID)”。结合 sql 来看,因为有 "ORDER BY TASK_ID DESC" 子句,排序通常很慢,如果使用了文件排序性能会更差,优化器选择这个索引避免了排序。
那为什么不选 possible_keys:INDX_BIOM_ELOCK_TASK 呢?原因也很简单,TASK_DATE 字段区分度太低了,走这个索引需要扫描的行数很大,而且还要进行额外的排序,优化器综合判断代价更大,所以就不选这个索引了。不过如果我们强制选择这个索引(用 force index 语法),会看到 SQL 执行速度更快少于 10s,那是因为优化器基于代价的原则并不等价于执行速度的快慢;
b. 再看执行计划中的 type:index,"index" 代表 “全索引扫描”,其实和全表扫描差不多,只是扫描的时候是按照索引次序进行而不是行,主要优点就是避免了排序,但是开销仍然非常大。
Extra:Using where 也意味着扫描完索引后还需要回表进行筛选。一般来说,得保证 type 至少达到 range 级别,最好能达到 ref。
在第 2 点中提到的“慢日志记录Rows_examined: 1161559,看起来是全表扫描”,这里更正为“全索引扫描”,扫描行数确实等于表的行数;
c. 关于执行计划中:“rows:644”,其实这个只是估算值,并不准确,我们分析慢 SQL 时判断准确的扫描行数应该以 slow log 中的 Rows_examined 为准。
4. 优化建议:添加组合索引 IDX_REL_DEVID_TASK_ID(REL_DEVID,TASK_ID)

优化过程:
TASK_DATE 字段存在索引,但是选择度很低,优化器不会走这个索引,建议后续可以删除这个索引:
select count(*),count(distinct TASK_DATE) from T_BIOMA_ELOCK_TASK;+------------+---------------------------+| count(*) | count(distinct TASK_DATE) |+------------+---------------------------+| 1161559 | 223 |+------------+---------------------------+

在这个 sql 中 REL_DEVID 字段从命名上看选择度较高,通过下面 sql 来检验确实如此:
select count(*),count(distinct REL_DEVID) from T_BIOMA_ELOCK_TASK;+----------+---------------------------+| count(*) | count(distinct REL_DEVID) |+----------+---------------------------+| 1161559 | 62235 |+----------+---------------------------+

由于有排序,所以得把 task_id 也加入到新建的索引中,REL_DEVID,task_id 组合选择度 100%:
select count(*),count(distinct REL_DEVID,task_id) from T_BIOMA_ELOCK_TASK;+----------+-----------------------------------+| count(*) | count(distinct REL_DEVID,task_id) |+----------+-----------------------------------+| 1161559 | 1161559 |+----------+-----------------------------------+

在测试环境添加 REL_DEVID,TASK_ID 组合索引,测试 sql 性能:alter table T_BIOMA_ELOCK_TASK add index idx_REL_DEVID_TASK_ID(REL_DEVID,TASK_ID);
添加索引后执行计划:
这里还要注意一点“隐式转换”:REL_DEVID 字段数据类型为 varchar,需要在 sql 中加引号:AND T.REL_DEVID = 000000025xxx >> AND T.REL_DEVID = '000000025xxx'

执行时间从 10s+ 降到 毫秒级别:
1 row in set (0.00 sec)
结论
一个典型的 order by 查询的优化,添加更合适的索引可以避免性能问题:执行计划使用索引并不意味着就能执行快。

⑻ SQL数据库索引怎么创建

方法如下: Oracle中建立索引,会提高查询速度: create index 索引名 on 表名(列名); 例如: create index index_userid on tbl_detail(userid); 如何找数据库表的主键字段的名称

⑼ SQL表字段如何建立索引难道就是添加SQL查询语句

1、创建测试表,

create table test_index(id varchar2(20), v_date date);

⑽ 如何解决SQL查询速度太慢

呵呵,这个问题很有趣不是吗?
上面的同志们只是给出一些建议,以我的经验来看(oracle),
如果数据量较大,索引的重复量尽量避免,最好的方式是建立非业务id(最好使用自增或是序列),把这个id建立索引。
你的最大的问题就是,建立了索引后,索引列必须出现在where中,否则索引就白白建立了,比如你的id是从1一直到383000,那么你的语句可以写成
select
*
from
hr_worktime
where
id>-1
还有就是,where条件中避免出现!=,or,between,等东西,否则索引实效。