我正在创建一个 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();
然后程序一直运行到最后。
感谢您的关注。