MySQL Union排序在不同的服务器上意外工作

时间:2017-03-21 00:09:09

标签: mysql database union mariadb

美好的一天,

我遇到“简单”查询的问题。当我在不同的服务器上执行它时,我得到了我需要的其他结果集。

我尝试通过export-> import重新导入所有“表格”,但仍无效。

哪里有问题?可能是MariaDB中的问题吗?

数据库版本:

  • 5.6.27 - MySQL社区服务器(GPL),客户端:libmysql 5.0.11-dev
  • 10.0.25- MariaDB -0 + deb8u1 - (Debian),客户端:libmysql 5.5.49

两者都在 MyISAM 引擎上运行。

查询:

ui <- fluidPage(
 sidebarLayout(
   sidebarPanel(
     actionButton("bb","bb"),
     sliderInput("aa","aa",value=1,min=0,max=10),
     sliderInput("aa1","aa1",value=1,min=0,max=10),
     sliderInput("aa2","aa2",value=1,min=0,max=10),
     sliderInput("aa3","aa3",value=1,min=0,max=10)
   )
   ,

   mainPanel(
     plotOutput("rys")
   )
 ) 
)


server <- function (input, output){
  output$rys <- renderPlot({qmap('Europe',zoom=4)})
}

shinyApp(ui = ui, server = server)

结果(左预期,右无效):

enter image description here

SQL说明(预期名列前茅,Bot无效)

enter image description here

2 个答案:

答案 0 :(得分:2)

ORDER BY不一定是稳定的。当您将ORDER BY应用于UNION的结果时,它可以在组内重新排序。

外部查询中不需要ORDER BY ordinary。当您使用UNION时,结果通常按子查询的顺序排列,因此第一个SELECT的结果将首先出现,之后的第二个SELECT结果。

但是,您应该将UNION更改为UNION ALL。默认情况下,它是UNION DISTINCT,这意味着它必须结合查询结果以删除重复项。由于查询之间永远不会有重复(因为它们有不同的ordinary列),这是不必要的。

另一个不依赖于此的解决方案(我实际上不确定它是否有保证)是从子查询中取出ORDER BY datum,并使用主查询:

ORDER by ordinary, IF(ordinary = 0, datum, '') ASC, IF(ordinary = 1, datum, '') DESC

答案 1 :(得分:0)

  • ANSI标准说可以忽略子查询中的ORDER BY。这相当于说表没有行的内在顺序。
  • 最近 Oracle和MariaDB(显然是独立的)开始利用这个标准。
  • UNION ALL是合适的,因为没有值重叠,并且由于没有重复传递,因此速度快于UNION DISTINCT
  • UNION 传统已经通过创建临时表来实现,将一个选择中的行提供给它,然后是下一个选择。
  • 最近在某些情况下消除了对临时表的需求。这是一个很好的优化。
  • future 中,我希望多个线程并行执行SELECTs。这将真正使您今天可能享受的关于事物或订购方式的任何假设无效。

底线:移除内部ORDER BYs并添加外部ORDER BY,例如@ Barmar的建议。

这样,您的查询将在MySQL / MariaDB的所有过去,当前和未来版本中“正确”运行。 (几年前我第一次被这个问题烧伤了:Here。)

与此同时,在完全删除InnoDB之前切换到InnoDB。