所以我有一个总结,我需要返回到最终用户应用程序。
它应该接受3个参数DateType,StartDate,EndDate。
日期类型将确定我用来过滤数据的日期字段。
我完成此操作的方法是将日期类型的记录的所有ID放入TEMP表,然后将我的摘要加入ID列表。
在运行包含数据的SQL服务器上运行查询时,这很好。
但是,这是一个复制的服务器,因此当我编译到存储过程中将存在其他应用程序数据的服务器时,它会减慢查询速度。 IE 2秒vs 50秒。
我认为从SQL服务器上创建的临时表开始交叉连接,然后加入到replciation服务器上的表,导致速度变慢。
我是否可以使用任何方法或技术来解决这个问题并在一个存储过程中构建所有这些方法或技术?
如果我使用自己的日期范围创建3个存储过程,那么它们会再次快速。但是,这意味着为同一件事维护多个存储过程。
答案 0 :(得分:0)
首先,如果您运行的是早于2012 SP1的SQL Server版本,则一个问题是不允许运行DBCC SHOW_STATISTICS
的用户(大多数不是系统管理员的用户,请参阅文档中的“权限”部分)无法访问远程表的统计信息。这可能严重削弱优化器生成良好执行计划的能力。升级SQL Server或授予更多权限可以帮助解决问题。
如果您的查询涉及过滤或加入字符列,请确保远程服务器在链接服务器选项中标记为“collation compatible”。如果此选项关闭,SQL Server不能假设可以跨服务器比较字符串,它将开始上下抽取整个表格,以确保数据最终在必须进行比较的地方。
如果执行计划尽可能好并且仍然不够好,那么一种通用(跛脚)技术是首先在本地传输所有数据(SELECT * INTO #localtable FROM remote.db.schema.table
),然后将查询作为非分布式运行查询。显然,为了使其工作,远程表不能“太大”,并且在某些情况下,这实际上具有更差的性能,这取决于涉及多少行。但它总是值得考虑,因为优化器在本地表中做得更好。
另一种避免跨服务器将表拉到一起的方法是将参数中的数据打包到远程存储过程调用中。整个表可以XML
通过NVARCHAR(MAX)
传递,因为分布式查询中不支持XML
列和表值参数。基本思想是相同的:避免优化器需要找出有效的分布式查询。显然,最好的方法在很大程度上取决于您的数据和查询。