草庐IT

sql - 使用大于运算符和 ORDER BY 的 MySQL 查询的索引帮助

coder 2023-10-03 原文

我有一个至少包含几百万行的表和一个包含所有整数的架构,大致如下所示:

start
stop
first_user_id
second_user_id

使用以下查询提取行:

SELECT * 
  FROM tbl_name 
 WHERE stop >= M 
   AND first_user_id=N  
   AND second_user_id=N 
ORDER BY start ASC

SELECT * 
  FROM tbl_name 
 WHERE stop >= M 
   AND first_user_id=N 
ORDER BY start ASC

我无法找到加速这些查询的最佳索引。问题似乎是 ORDER BY,因为当我取出它时,查询速度很快。

我已经使用标准索引格式尝试了所有不同类型的索引:

ALTER TABLE tbl_name ADD INDEX index_name (index_col_1,index_col_2,...)

而且它们似乎都不能加快查询速度。有谁知道什么索引会起作用?另外,我应该尝试不同类型的索引吗?我无法保证每一行的唯一性,因此我避免使用 UNIQUE 索引。

任何指导/帮助将不胜感激。谢谢!

更新:这里有一个索引列表,我最初没有包括这个,因为我采用了散弹枪方法并添加了大量索引来寻找一个有效的索引:

start_index: [start, first_user_id, second_user_id]
stop_index: [stop, first_user_id, second_user_id]
F1_index: [first_user_id]
F2_index: [second_user_id]
F3_index: [another_id]
test_1_index: [first_user_id,stop,start]
test_2_index: [first_user_id,start,stop]
test_3_index: [start,stop,first_user_id,second_user_id]
test_4_index: [stop,first_user_id,second_user_id,start]
test_5_index: [stop,start]

这是 EXPLAIN 输出。

*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: listing
type: index_merge
possible_keys: stop_index,F1_index,F3_index,test_1_index,test_2_index,test_4_index,test_5_index
key: F1_index,F3_index
key_len: 5,5
ref: NULL
rows: 238
Extra: Using intersect(F1_index,F3_index); Using where; Using filesort

后代更新

我们最终完全重新评估了查询表的方式并选择了这些索引:

index_select_1: [first_user_id,start,stop]
index_select_2: [first_user_id,second_user_id,start,stop]

然后我们使用如下查询在表上进行选择:

SELECT * 
  FROM tbl_name 
 WHERE first_user_id=N
   AND start >= M 
ORDER BY start ASC

SELECT * 
  FROM tbl_name 
 WHERE first_user_id=N   
   AND second_user_id=N
   AND start >= M 
ORDER BY start ASC

感谢所有回答的人,你们真的帮我想通了这个问题。

最佳答案

你能让你的示例表和 EXPLAIN 结果匹配吗? 因为,显然情况不同,我们不知道您是否仅通过查看提供的 EXPLAIN 结果在抽象真实查询时犯了错误。 如果您不想显示太多结构,则将其反转并创建引用的表结构并提供 EXPLAIN 结果(也许您会以这种方式发现问题)。

现在可以确定一件事 - 排序正在使用 filesort ,这很糟糕。

为了简化(我们会回来讨论它)- 用于排序的复合索引需要在前面有排序字段。

例子 idx(ID, 开始)

ID      Start
1
        5
        8
        8
        10
        25
2
        3
        9
        10
        40
        41
        42
        42
...

在上面的示例中,如果您没有将 ID 限制为仅一个值的 where 条件,则索引对排序没有多大帮助。

但是,这个异常(exception)很重要,因为您在一个或两个 id 字段上有单行选择性。

所以从你的索引中,唯一从头开始的索引是

start_index: [start, first_user_id, second_user_id]
test_3_index: [start,stop,first_user_id,second_user_id]

Mysql忽略索引

start_index: [start, first_user_id, second_user_id]

因为它在选择性方面有更好的选择 - 它需要使用该索引进行索引扫描,并且它具有允许它进行索引相交直接跳转到(未排序的)结果的索引。它期望从相交处获得更好的选择性,并且选择性驱动刨床。

一旦得到结果,mysql 应该意识到它可以使用另一个索引来对结果进行排序,但它似乎看不出这样做会有多便宜。

因此,为了帮助规划者,您可以创建一个索引,该索引将利用您的单值选择性索引,例如:

two_ids_with_sort: [first_user_id, second_user_id, start]

我假设上面的方法在你的第二个查询上工作得很好,你在两个 id 上都有条件,让你可以访问预排序的开始记录指针。以下查询应该对第一个查询执行相同的操作:

one_id_with_sort: [first_user_id, start]

只有当您最终在结果集中有很多记录时,我才会考虑进一步索引它。

那里有两条路 a) 将字段停止添加到索引的末尾 b) 使用 stop 而不是 start 创建两个更相似的索引(可以在那里使用索引相交,并且更广泛的查询可以从中受益)

但请务必检验上述所有理论。

几个一般性建议

  • 首先以最有选择性的方式写下您的条件
  • 当测试索引首先从单列索引开始,然后扩展到复合索引时(例如,对于开始排序,我只会在开始时添加索引)
  • 太多的索引在 mysql 中不是很好,因为查询规划器不能快速运行所有可能的组合并且不能正确估计所有操作的成本(所以它偷工减料,最好的索引组合和计划可能被排除在外)
  • 因此,在您的选择中使用 USE INDEX (index1) FOR ORDER BY 测试索引,以衡量某个索引相对于 planer 的好处,查看更多 here (特别是 FORCE 选项;还有——旨在只留下有用的索引,看看 planer 是否能够利用它们,如果不能,作为最后的手段,在你的查询中强制使用性能至关重要的索引。记住这在管理和设计方面是一种不好的做法)。

关于sql - 使用大于运算符和 ORDER BY 的 MySQL 查询的索引帮助,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2405128/

有关sql - 使用大于运算符和 ORDER BY 的 MySQL 查询的索引帮助的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 使用 RubyZip 生成 ZIP 文件时设置压缩级别 - 2

    我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看ruby​​zip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d

  3. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

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

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

  5. ruby - 在 Ruby 中使用匿名模块 - 2

    假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于

  6. ruby - 使用 ruby​​ 和 savon 的 SOAP 服务 - 2

    我正在尝试使用ruby​​和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我

  7. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  8. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  9. ruby - ECONNRESET (Whois::ConnectionError) - 尝试在 Ruby 中查询 Whois 时出错 - 2

    我正在用Ruby编写一个简单的程序来检查域列表是否被占用。基本上它循环遍历列表,并使用以下函数进行检查。require'rubygems'require'whois'defcheck_domain(domain)c=Whois::Client.newc.query("google.com").available?end程序不断出错(即使我在google.com中进行硬编码),并打印以下消息。鉴于该程序非常简单,我已经没有什么想法了-有什么建议吗?/Library/Ruby/Gems/1.8/gems/whois-2.0.2/lib/whois/server/adapters/base.

  10. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

    我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

随机推荐