草庐IT

asp.net - SQL排序,分页,过滤ASP.NET中的最佳实践

coder 2023-10-10 原文

我想知道谷歌是怎么做到的。当涉及到页面计数和结果总数时,我有很多慢查询。google在几秒钟内返回一个250000,00的计数值。
我正在处理网格视图。我为gridview构建了一个自定义分页器,它需要一个sql查询来返回基于用户设置的过滤器的页面计数。过滤器至少有5个,其中包括关键字、类别和子类别、日期范围过滤器以及用于排序的排序表达式过滤器。查询包含大约10个大型表左连接。
每次执行搜索时都会执行此查询,并且查询执行平均持续30秒—无论是计数还是选择。我相信让它变慢的是我的包含和排除日期范围过滤器的查询字符串。我已将(<=,>=)替换为介于和和之间,但仍然遇到相同的问题。
请参见此处的查询:
http://friendpaste.com/4G2uZexRfhd3sSVROqjZEc
我对长日期范围参数有问题。
检查包含日期的“我的表”:
http://friendpaste.com/1HrC0L62hFR4DghE6ypIRp
更新[9/17/2010]我最小化了日期查询并删除了时间。
我尝试减少count查询的连接(实际上,我的过滤器计数有问题,需要很长时间才能返回60k行的结果)。

      SELECT COUNT(DISTINCT esched.course_id)
        FROM courses c
           LEFT JOIN events_schedule esched
              ON c.course_id = esched.course_id
           LEFT JOIN course_categories cc
              ON cc.course_id = c.course_id
           LEFT JOIN categories cat
              ON cat.category_id = cc.category_id
     WHERE     1 = 1
           AND c.course_type = 1
           AND active = 1
           AND c.country_id = 52
           AND c.course_title LIKE '%cook%'
           AND cat.main_category_id = 40
           AND cat.category_id = 360
 AND (

    (2010-09-01' <= esched.date_start OR 2010-09-01' <= esched.date_end) 
    AND

    ('2010-09-25' >= esched.date_start OR '2010-09-25' >= esched.date_end)     
   )

我刚刚注意到,当我对主类别或子类别字段进行筛选时,我的查询速度相当快。然而,当我只有一个日期过滤器,范围是一个月或一周,它需要计算很多行,平均在30秒内完成。
这些是静态字段:
AND c.course_type = 1
AND active = 1
AND c.country_id = 52

更新[9/17/2010]如果a为这三个字段创建散列并将其存储在一个字段上,它是否会改变速度?
以下是我的动态字段:
AND c.course_title LIKE '%cook%'
AND cat.main_category_id = 40
AND cat.category_id = 360
// ?DateStart and ?DateEnd

更新[9/17/2010]。现在我的问题是like查询中的前导%
将发布更新的解释

最佳答案

像谷歌这样的搜索引擎使用非常复杂的幕后算法来索引搜索。基本上,他们已经确定了每一页上出现的单词以及这些单词的相对重要性和页面的相对重要性(相对于其他页面)。这些索引非常快,因为它们基于按位索引。
考虑以下谷歌搜索:

custom : 542 million google hits
pager : 10.8 m
custom pager 1.26 m

实际上,他们所做的是为单词custom创建一个记录,在该记录中,他们为每个包含该记录的页面放置了1,为每个不包含该记录的页面放置了0。然后他们把它拉起来,因为0s比1s多得多。他们对寻呼机也这样做。
当搜索custom pager进入时,它们会解压缩两个记录,对它们执行按位“与”运算,这将生成一个位数组,其中“长度”是它们索引的总页数,而“1”表示搜索的命中数。每一位的位置对应于一个事先已知的特定结果,它们只需查找前10位的全部细节就可以显示在第一页上。
这过于简单化了,但这是一般原则。
哦,是的,他们也有庞大的服务器库执行索引,庞大的服务器库响应搜索请求。庞大的服务器库!
这使得它们比关系数据库中的任何操作都要快得多。
现在,针对您的问题:您可以粘贴一些示例sql供我们查看吗?
可以尝试的一件事是更改表和联接在sql语句中的显示顺序。我知道这似乎不应该有什么不同,但肯定可以。如果在语句的前面放置最严格的连接,那么最终在数据库中执行的总连接可能会更少。
一个真实的例子。假设您想在电话簿中找到所有名为“johnson”的条目,号码以“7”开头。一种方法是查找所有以7开头的数字,然后将其与属于“johnson”的人的数字连接起来。事实上,即使在名称和数字上都有索引,用另一种方法执行过滤也要快得多。这是因为“johnson”这个名字比数字7更严格。
因此,顺序是有价值的,而datbase软件并不总是善于预先确定要先执行哪个连接。我不确定my sql,因为我的经验主要是使用sql server,它使用索引统计来计算执行连接的顺序。在多次插入、更新和删除之后,这些统计数据就会过期,因此必须定期重新计算它们。如果mysql有类似的东西,可以试试这个。
更新
我看过你发来的查询。十个左连接并不罕见,只要有正确的索引,就应该执行得很好。你的问题并不复杂。
您需要做的是将此查询分解为基本查询。注释掉查找连接,如货币、课程统计、国家、州和城市以及select语句中的相应字段。它还跑得那么慢吗?可能不是。但这可能仍不理想。
因此,请注释掉所有其他内容,直到您只拥有课程和按课程ID分组和按课程ID排序的组。然后,尝试添加左连接以查看哪个连接的影响最大。然后,将重点放在对性能影响最大的查询上,更改查询的顺序。这是试错法。对您来说,查看要连接的列上的索引会更好。
例如,cm.method_id = c.method_id行需要一个course_methodology.method_id上的主键和一个courses.method_id上的外键索引,等等。此外,where、group by和order by子句中的所有字段都需要索引。
祝你好运
更新2
您真的需要查看此查询的日期筛选。你想干什么?
   AND ((('2010-09-01 00:00:00' <= esched.date_start
          AND esched.date_start <= '2010-09-25 00:00:00')
         OR ('2010-09-01 00:00:00' <= esched.date_end
             AND esched.date_end <= '2010-09-25 00:00:00'))
        OR ((esched.date_start <= '2010-09-01 00:00:00'
             AND '2010-09-01 00:00:00' <= esched.date_end)
            OR (esched.date_start <= '2010-09-25 00:00:00'
                AND '2010-09-25 00:00:00' <= esched.date_end)))

可以重写为:
AND (

    //date_start is between range - fine
    (esched.date_start BETWEEN '2010-09-01 00:00:00' AND '2010-09-25 00:00:00') 

    //date_end is between range - fine
    OR (esched.date_end BETWEEN '2010-09-01 00:00:00' AND '2010-09-25 00:00:00')       

    OR (esched.date_start <= '2010-09-01 00:00:00' AND esched.date_end >= '2010-09-01 00:00:00' ) 

    OR (esched.date_start <= '2010-09-25 00:00:00' AND esched.date_end > = '2010-09-25 00:00:00')
  )

关于asp.net - SQL排序,分页,过滤ASP.NET中的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3701132/

有关asp.net - SQL排序,分页,过滤ASP.NET中的最佳实践的更多相关文章

  1. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  2. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  3. ruby - 其他文件中的 Rake 任务 - 2

    我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时

  4. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  5. ruby-on-rails - Rails 3 中的多个路由文件 - 2

    Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题

  6. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  7. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  8. ruby-on-rails - Rails 应用程序中的 Rails : How are you using application_controller. rb 是新手吗? - 2

    刚入门rails,开始慢慢理解。有人可以解释或给我一些关于在application_controller中编码的好处或时间和原因的想法吗?有哪些用例。您如何为Rails应用程序使用应用程序Controller?我不想在那里放太多代码,因为据我了解,每个请求都会调用此Controller。这是真的? 最佳答案 ApplicationController实际上是您应用程序中的每个其他Controller都将从中继承的类(尽管这不是强制性的)。我同意不要用太多代码弄乱它并保持干净整洁的态度,尽管在某些情况下ApplicationContr

  9. ruby - 如何模拟 Net::HTTP::Post? - 2

    是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou

  10. ruby-on-rails - form_for 中不在模型中的自定义字段 - 2

    我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢

随机推荐