我的应用程序有一组固定的SQL查询。这些查询以轮询模式运行,持续10秒。
由于数据库的大小(> 100 GB)和设计(uber规范化),我遇到了性能问题。
每当在更改查询结果的数据库上发生CRUD事件时,是否可以对给定查询进行增量更改?即如果我查询所有姓FOO的员工,那么每当a)新员工加入姓FOO时,我都会收到通知b)姓名FOO的员工被解雇等等。
我正在运行SQL Server 2005,顺便说一句。
谢谢!
编辑:澄清一下,数据库大小为100GB。查询不是存储过程。数据库是SQL Server 2005(但如果需要可以升级到2008)。因为数据非常规范化,所以在查询中我有9或10个表的JOIN。因此这些查询非常慢。即使有索引。
目前,当轮询开始时,我在整个数据库上运行查询。是否有任何记录已更改。理想情况下,我想做的是注册我的查询 与服务器一起使用,并在查询结果集发生任何更改时收到通知。因此,如果添加的记录与我的查询匹配,只需通知我这一更改。 我认为这比在轮询循环中重新运行整个查询更好。这就是我的意思。这样,我可以将更改推送到我的客户端,并摆脱轮询。再次感谢所有评论!
答案 0 :(得分:2)
您可以使用触发器记录中间表中的更改,然后在计划脚本中处理修改。 为了捕获更改,SQL Server 2008引入了一项名为CDC的新功能。有关CDC的更多详细信息,请查看以下文章:
http://blog.sqlauthority.com/2009/09/01/sql-server-download-script-of-change-data-capture-cdc/
答案 1 :(得分:1)
对不起,但是标准化比非标准化要快10到100次次(有许多非标准化的文件集合!)。
您是否每10秒钟认真返回100GB结果集?这可能是一个愚蠢的事情(无论数据库是否规范化)。你正在锤击服务器并使用100GB的数据充斥网络,其中99%的数据每10秒钟不会改变。
“每当在更改[previous]查询结果的数据库上发生CRUD事件时,是否可以对给定查询进行增量更改?”
绝对。 ANSI SQL提供了某些基础知识,供应商提供了扩展。当然,被事件唤醒比投票更好,但在你的情况下,这不是问题。如果db中有一些标准,那么只获得有变化的行就不费吹灰之力了。合理的系统具有TIMESTAMP或DATETIME列,用于防止丢失更新和乐观锁定。如果你有这个,并且服务器可以相互RPC,那么编写只更新(删除,插入)那些已经发生变化的行的SQL代码就非常简单。
如果您没有实现这样的列,那么您可以将它们放入(不需要更改应用程序代码),或者编写丑陋的代码来检查每行中的每一列(不推荐。)
如果您有Sybase,它会提供通知(取消轮询)。
但问题是,为什么你需要将整个数据库复制到其他位置?
Sybase和其他人有一个产品可以复制数据(消除你的应用程序每10秒移动100GB)。
答案 2 :(得分:1)
我同意,DML触发听起来像你最好的选择。当插入/更新/删除发生时,SQL会触发一个事件。然后,您可以使用此事件更新另一个表。但是在经常更新的表格中,这会产生不受欢迎的开销。
http://msdn.microsoft.com/en-us/library/ms178110.aspx
扩展事件和CDC是2008年的功能,因此它们已经出局。
“我的应用程序有一组固定的SQL查询” - 这些是存储过程吗?
优化每10秒运行一次的查询? SARGable参数?一个很好的可重用查询计划。