简体   繁体   English

在没有SqlDataSource对象的情况下加快查询SQL Server 2008 R2的方法

[英]Ways to speed up queries SQL Server 2008 R2 without SqlDataSource object

I'm trying to build a product catalog application in ASP.NET and C# that will allow a user to select product attributes from a series of drop-down menus, with a list of relevant products appearing in a gridview. 我正在尝试在ASP.NET和C#中构建产品目录应用程序,该应用程序将允许用户从一系列下拉菜单中选择产品属性,并在gridview中显示相关产品的列表。

On page load, the options for each of the drop-downs are queried from the database, as well as the entire product catalog for the gridview. 在页面加载时,从数据库中查询每个下拉菜单的选项以及gridview的整个产品目录。 Currently this catalog stands at over 6000 items, but we're looking at perhaps five or six times that when the application goes live. 目前,该目录包含6000多个项目,但是当应用程序上线时,我们的目光可能是该目录的五到六倍。

The query that pulls this catalog runs in less than a second when executed in SQL Server Management Studio, but takes upwards of ten seconds to render on the web page. 在SQL Server Management Studio中执行该查询时,拉出此目录的查询将在不到一秒钟的时间内运行,但要花费十秒钟以上的时间才能在网页上呈现。 We've refined the query as much as we know how: pulling only the columns that will show in our gridview (as opposed to saying select * from ... ) and adding the with (nolock) command to the query to pull data without waiting for updates, but it's still too slow. 我们已经对查询进行了尽可能多的优化:仅提取将在gridview中显示的列(而不是说select * from ... ),并在查询中添加with (nolock)命令以提取不包含数据的数据等待更新,但速度仍然太慢。

I've looked into SqlCacheDependency , but all the directions I can find assume I'm using a SqlDataSource object. 我已经研究了SqlCacheDependency ,但是所有可以找到的说明都假设我正在使用SqlDataSource对象。 I can't do this because every time the user makes a selection from the menu, a new query is constructed and sent to the database to refine the list of displayed products. 我无法执行此操作,因为每次用户从菜单中进行选择时,都会构造一个新查询并将其发送到数据库以精炼所显示产品的列表。

I'm out of my depth here, so I'm hoping someone can offer some insight. 我不在这里,我希望有人可以提供一些见解。 Please let me know if you need further information, and I'll update as I can. 如果您需要更多信息,请告诉我,我会尽快更新。

EDIT: FYI, paging is not an option here. 编辑:仅供参考,分页不是这里的选项。 The people I'm building this for are standing firm on that point. 我为此而努力的人在这一点上坚定不移。 The best I can do is wrap the gridview in a div with overflow: auto set in the CSS. 我能做的最好的就是将gridview包裹在div中,并带有溢出:在CSS中自动设置。

The tables I'm dealing with aren't going to update more than once every few months, if that; 我正在处理的表每隔几个月不会更新一次以上。 is there any way to cache this information client-side and work with it that way? 有什么办法可以在客户端缓存此信息并以这种方式使用它?

Most of your solution will come in a few forms (none of which have to do with a Gridview): 您的大多数解决方案都将以几种形式出现(与Gridview无关):

  1. Good indexes. 良好的索引。 Create good indexes for the tables that pull this data; 为提取该数据的表创建良好的索引; good indexes are defined as: 好的索引定义为:

    • Indexes that store as little information as actually needed to display the product. 索引只存储显示产品所需的实际信息。 The smaller the amount of data stored, the greater amount of data can be stored per 8K page in SQL Server. 存储的数据量越少,SQL Server中每8K页可以存储的数据量越大。
    • Covering indexes: Your SQL Query should match exactly what you need (not SELECT * ) and your index should be built to cover that query (hence why it's called a 'covering index') 覆盖索引:您的SQL查询应该完全符合您的需求(而不是SELECT * ),并且应该构建索引来覆盖该查询(因此将其称为“覆盖索引”)
  2. Good table structure: this goes along with the index. 良好的表结构:与索引一起使用。 The fewer joins needed to pull the information, the faster you can pull it. 提取信息所需的联接越少,则提取信息的速度就越快。

  3. Paging. 寻呼。 You shouldn't ever pull all 6000+ objects at once -- what user can view 6000 objects at once? 您永远不要一次拉出所有6000多个对象-哪个用户可以一次查看6000个对象? Even if a theoretical superhuman could process that much data; 即使理论上的超人可以处理那么多数据; that's never going to be your median usecase. 那永远不会成为您的中值用例。 Pull 50 or so at a time (if you really even need that many) or structure your site such that you're always pulling what's relevant to the user, instead of everything (keep in mind this is not a trivial problem to solve) 一次拉50个左右(如果您确实需要那么多)或构建网站,以便始终拉动与用户相关的内容,而不是拉动所有内容(请记住,这并不是要解决的琐碎问题)

The beautiful part of paging is that your clients don't even need to know you've implemented paging. 分页的美丽之处在于您的客户甚至不需要知道您已经实现了分页。 One such technique is called " Infinite Scrolling ". 一种这样的技术称为“ 无限滚动 ”。 With it, you can go ahead and fetch the next N rows while the customer is scrolling to them. 有了它,您可以继续并在客户滚动到它们时获取下N行。

If, as you're saying paging really is not an option (although I really doubt it ; please explain why you think it is, and I'm pretty sure someone will find a solution), there's really no way to speed up this kind of operation. 如果(正如您所说的那样)分页确实不是一种选择(尽管我真的对此表示怀疑;请解释一下为什么您认为分页,并且我很确定有人会找到解决方案),但实际上没有办法加快这种分页的速度操作。

As you noticed, it's not the query that's taking long, it's the data transfer. 正如您所注意到的,不是花费很长时间的查询,而是数据传输。 Copying the data from one memory space (sql) to another (your application) is not that fast, and displaying this data is orders of magnitude slower. 将数据从一个内存空间(sql)复制到另一个(您的应用程序)的速度并不快,并且显示此数据的速度要慢几个数量级。

Edit: why are your clients "firm on that point" ? 编辑:为什么您的客户“在这一点上坚定”? Why do they think it's not possible otherwise ? 他们为什么认为否则不可能呢? Why do they think it's the best solution ? 他们为什么认为这是最佳解决方案?

There are many options to show a big largeset of data on a grid but third parties software. 有很多选项可以在网格上显示大量数据,但第三方软件可以显示。 Try to use jquery/javascript grids with ajax calls. 尝试对ajax调用使用jquery / javascript网格。 It will help you to render on client a large amount of rows. 它将帮助您在客户端上呈现大量行。 Even you can use the cache to not query many times the database. 甚至您也可以使用缓存来查询数据库多次。 Those are a good grids that will help your to show thousands of rows on a web browser: 这些是一个很好的网格,可以帮助您在网络浏览器上显示数千行:

  1. http://www.trirand.com/blog/ http://www.trirand.com/blog/
  2. https://github.com/mleibman/SlickGrid https://github.com/mleibman/SlickGrid
  3. http://demos.telerik.com/aspnet-ajax/grid/examples/overview/defaultcs.aspx http://demos.telerik.com/aspnet-ajax/grid/examples/overview/defaultcs.aspx
  4. http://w2ui.com/web/blog/7/JavaScript-Grid-with-One-Million-Records http://w2ui.com/web/blog/7/JavaScript-Grid-with-One-Million-Records

I Hope it helps. 希望对您有所帮助。

You can load all the rows into a Datatable on the client using a Background thread when the application (Web page) starts. 当应用程序(网页)启动时,您可以使用后台线程将所有行加载到客户端上的数据表中。 Then only use the Datatable to populate your Grids etc....So you do not have to hit SQL again until you need to read / write different data. 然后仅使用数据表填充网格等。因此,您不必再次命中SQL,直到需要读取/写入其他数据为止。 (All the other answers cover the other options) (所有其他答案涵盖其他选项)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM