0

我正在创建一个 Java 函数,该函数需要在对其结果进行全面扫描之前使用带有大量连接的 SQL 查询。我决定用这个复杂的查询创建一个视图,而不是对很多连接进行硬编码。然后 Java 函数只使用以下查询来获取此结果:

SELECT * FROM VW_####

所以程序运行良好,但我想让它更快,因为这个SELECT命令需要很多时间。在查看了它的计划执行计划后,我创建了一些索引并使其速度提高了 +-30%,但我想让它更快。

问题是执行计划中的每个操作的成本都在 0% 到 4% 之间,除了一个操作,即具有 +-50% 执行成本的聚集索引插入。我认为系统正在使用一个临时表来存储视图的数据,但是这个视图中的索引对我没有用,因为我需要它的所有行。

那么我可以做些什么来优化该插入CWT_PrimaryKey?我认为我无法关闭该索引,因为它似乎是 SQL Server 内部结构的一部分。我在某处读到,当您使用游标时可能会出现此操作,但我认为我没有使用(或者视图是否使用它?)。

创建视图的命令很简单(没有 T-SQL,没有 OPTION 等),例如:

create view VW_#### as SELECTS AND JOINS HERE

这是执行计划中有问题的部分的图片:http: //imgur.com/PO0ZnBU

编辑:更多细节:

那么创建有问题的视图的查询是一个连接很多表的大查询。Java-Client 基于单个参数在创建查询字符串之前对其进行修改。此视图表示从遗留数据库迁移到没有任何外键或主键的 SQLServer 的“数据单元”,因此我们的团队选择遵循此策略。因此,该视图有 50 多个列,并且它是由其他七个视图的连接组成的。

主视图的查询(有很多葡萄牙语单词): http: //pastebin.com/Jh5vQxzA

其他视图(从 VW_Sintese1 到 VW_Sintese7)的创建方式与此类似,但不使用额外的视图,它们仅使用包含主视图请求的数据的表的连接。

然后,Java 客户端使用查询“Select * from VW_Sintese####”创建一个准备好的语句,并使用函数“ExecuteQuery”执行它,例如:

String query = "Select * from VW_Sintese####";
PreparedStatement ps = myConn.prepareStatement(query,ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
ResultSet rs = ps.executeQuery();

然后程序一直运行到最后。

感谢您的关注。

4

1 回答 1

0

首先:您应该发布视图的代码以及使用视图的任何内容,因为这个答案的其余部分。

第二:SQL Server 中视图的定义后来用于查询中的替换。换句话说,您创建了一个视图,但由于(我假设)它不是索引视图,因此它与编写原始的长 SELECT 语句相同。SQL Server 只是在 DML 语句中将其换出。

来自 Microsoft 的“Querying Microsoft SQL Server 2012”:T-SQL 支持以下表表达式:派生表、公用表表达式 (CTE)、视图、内联表值函数。

并直接引用:

It’s important to note that, from a performance standpoint, when SQL Server optimizes queries involving table expressions, it first unnests the table expression’s logic, and therefore interacts with the underlying tables directly. It does not somehow persist the table expression’s result in an internal work table and then interact with that work table. This means that table expressions don’t have a performance side to them—neither good nor bad—just no side.

这是加强第一条语句的漫长方法:请在视图中包含 SQL 代码以及您实际使用的SELECT语句。否则,我们无能为力:) 干杯!

编辑:好的,所以您已经创建了一个视图(那里没有性能提升),它LEFT JOIN在主视图上执行 4-5 (同样,通过消除行等,您在这里并没有帮助自己太多)。如果有搜索参数可用于将结果集过滤到更少的行,那么您应该在此处拥有这些参数。最后,您将所有这些都排序在顶部,因此您的查询引擎将必须获取这些视图,将它们加入到一个庞大的SELECT语句中,找出正确的顺序,以及(我猜这里)结果计数是巨大的,SQL 的数据库引擎正在某种临时表中对其进行排序。

简短的回答:获取更少的数据(更少的列,只有你需要的行);如果结果集非常大,不要对结果进行排序,只需将数据获取到客户端,然后在那里进行排序。

同样,如果您需要更多帮助,您需要为查询中的所有表(包括连接的视图)发布表模式和索引策略,并且您需要包括所有视图定义(包括已加入)。

于 2014-01-25T04:18:47.887 回答