我需要一个Microsoft SQL Server 2005或更高版本的存储过程,它将创建大量的行(例如:一百万),这样我就可以尝试各种各样的事情,比如看看SELECT*与选择每个单独的字段名称相比有多慢,或者选择从另一个视图中选择的视图,而不是直接从表中选择.那有意义吗?
如果它只是您想要的行数,并且您不介意在每行中具有相同的内容,那么您可以轻松地在SQL Server Management Studio中执行此操作.编写插入语句以插入单行,然后使用:
GO 1000000
Run Code Online (Sandbox Code Playgroud)
这将执行批处理GO语句后指定的次数.
如果你每行需要不同的数据(或者由于索引等而不能有重复的数据......),那么有一些工具如SQL Data Generator会有所帮助.它们使您能够定义生成的数据类型,以便工具生成实际数据.
我现在可以告诉你这是多么慢执行SELECT *,而不是SELECT specific_column_names.如果您选择的列未被任何索引覆盖,则几乎不会产生任何差异; 如果你通常会选择列是由索引覆盖,表包含任何数据显著量,这将是一个数量级慢,还有可能变得更糟.
这是一个快速而肮脏的例子.首先创建测试模式和数据:
CREATE TABLE #TestTable
(
ID int NOT NULL IDENTITY(1, 1) PRIMARY KEY CLUSTERED,
Name varchar(50) NOT NULL,
Age int NOT NULL
)
INSERT #TestTable (Name, Age)
SELECT 'John', s1.number % 10 + 25
FROM master.dbo.spt_values s1
CROSS JOIN master.dbo.spt_values s2
WHERE s1.type = 'P' AND s2.type = 'P'
AND s2.number < 20
CREATE INDEX IX_#TestTable_Age ON #TestTable (Age)
Run Code Online (Sandbox Code Playgroud)
现在在SSMS中运行此查询并打开实际的执行计划:
SELECT ID
FROM #TestTable
WHERE Age = 30
SELECT *
FROM #TestTable
WHERE Age = 30
Run Code Online (Sandbox Code Playgroud)
第一个SELECT作为索引搜索执行,在我的机器上占总成本的7%.在第二个查询中,优化器确定IX_#TestTable_Age索引不值得并且进行聚簇索引扫描,使用总成本的93%,或者非SELECT *版本的13倍.
如果我们强制进行嵌套循环键查找,以模仿聚集索引或非常大的聚簇索引的缺失,则会变得更糟:
SELECT *
FROM #TestTable
WITH (INDEX(IX_#TestTable_Age))
WHERE Age = 30
Run Code Online (Sandbox Code Playgroud)
这需要覆盖查询的100倍以上.与第一个查询相比,成本只是天文数字.
在开始外出并"测试"事情之前,你需要摆脱常见的误解,即你编写查询语句的确切顺序,或者从其他视图中选择的视图等不相关的因素,如果你的数据库是甚至远程优化.
索引是数据库性能领域的第一件事.你如何使用它们是第二件重要的事情.编写查询的方式可能很重要 - 比如SELECT *在WHERE条件不是聚集索引的情况下执行,或者DATEPART在WHERE条件中使用不可搜索的函数,但在大多数情况下,丢弃一堆随机数据在没有认真考虑如何实际使用表格的情况下进入表格会在性能方面给你带来无意义的结果.
在规划大型项目并需要执行可伸缩性测试时,数据生成器非常有用.如果你只是在试验,尝试从抽象意义上理解不同类型的查询之间的性能差异,那么我不得不说你最好只是抓取一个Northwind或AdventureWorks数据库的副本并敲打那个- 它已经规范化并编入索引,您将能够在实际生产数据库中收集有关查询性能的有意义信息.
但更重要的是,在您开始考虑 SQL数据库中的性能之前,您需要实际开始阅读性能并了解哪些因素会影响性能. 正如我所提到的,首要因素是索引.其他因素包括排序顺序,选择性,连接类型,游标类型,计划缓存等.不要只是开始愚弄,认为你将学习如何最好地优化数据库.
在摸索前教育自己.我将从Microsoft模式和实践中稍微过时但仍然全面的改进SQL Server性能文章开始.另请阅读有关索引基础知识和覆盖索引的信息.然后转到SQL Server Performance等网站,尝试从文章中吸收任何内容.
那么,只有这样,你才能开始使用大规模的测试数据.如果你还没有完全确定为什么SELECT *会损害性能那就方式为时过早运行测试.
| 归档时间: |
|
| 查看次数: |
3227 次 |
| 最近记录: |