mysql - 添加第三个 LEFT JOIN 时查询速度很慢

标签 mysql sql join

你好,我一直在玩这个查询,但我无法让它在合理的执行时间内返回结果。

情况是这样的:

我有三个表-

表 1 调用:rowsall

 1  id          int(11) 
 2  masterCaseId    varchar(50)
 3  RowNum  int(11)
 4  fullCaseNumber  varchar(50)
 5  rowKtavNameFull varchar(250)
 6  DateOpen    varchar(50)
 7  DateProccess    varchar(50)
 8  rowStatus   varchar(50)
 9  rowCourt    varchar(100)
 10 rowProcedure    varchar(50)
 11 rowCaseType varchar(50)
 12 rowIntrest  varchar(50)
 13 rowDetailsGen   varchar(250)
 14 rowTypeTeanot   varchar(50)
 15 rowHisayon  varchar(50)
 16 rowAmount   varchar(50)
 17 rowZacautPtor   varchar(50)
 18 rowZacautApproove   varchar(50)
 19 rowStatIravon   varchar(50)
 20 rowDateClose    varchar(50)
 21 rowCloseReason  varchar(50)
 22 rowResultTaken  varchar(50)
 23 rowOldFile          varchar(50)
 24 rowOpenedInCourse   varchar(50)
 25 rowGniza            varchar(50)
 26 rowReasonDeposit    varchar(50)
 27 rowTypeJudgeType    varchar(50)
 28 rowJudgeTypeDate
 29 rowJudgeTypeName    varchar(50)
 30 rowGishurType   varchar(50)
 31 rowGishurDetails    varchar(250)

   Total rows: 13001, size 11.7mb

   Indexes:
   PRIMARY  BTREE   Yes No  id  13001   A   No  
   RowNum   BTREE   No  No  RowNum  12  A   No  
                            rowStatus   12  A   No
                            rowResultTaken  12  A   No
   rowJudgeTypeName BTREE   No  No  rowJudgeTypeName    1083    A   No  
   masterCaseId BTREE   No  No  masterCaseId    13001   A   No  
   RowNum_2 BTREE   No  No  rowJudgeTypeName    1857    A   No  
                            RowNum  1857    A   No
   fullCaseNumber   BTREE   No  No  fullCaseNumber  203 A   No  

表 2 调用:casses_rows

 1  id  int(11)
 2  caseFullNum varchar(50)
 3  statusCrawl varchar(50)
 4  courtPlace  text
 5  rowsNum int(11)
 6  caseJudge   varchar(50)
 7  caseFullName    text
 8  whenCrawled datetime
 9  yearVal varchar(5)
 10 monthVal    varchar(5)
 11 caseVal int(11)

   Total rows: ~23,846, size 4.8mb

   Indexes:
   PRIMARY  BTREE   Yes No  id  26302   A   No  

表 3 调用:casedocs

 1  id  int(11)
 2  caseNum varchar(20)
 3  DocTitle    varchar(250)
 4  DocDateStr  varchar(20)
 5  KeyWords    text
 6  content text
 7  DocDateParsed   timestamp

   Total rows: ~1,163,669, size 4.1g

   Indexes:
   PRIMARY  BTREE   Yes No  id  895132  A   No  
   caseNum  BTREE   No  No  caseNum 895132  A   No  

我的目标:

我需要连接这些表以获取表 1 中的大部分列 + 表 2 中的一个列 + 表 3 中的一个列,如果没有匹配项,则为 NULL:

我的查询是:

SELECT 
       A.`id` AS idRowCase, 
       C.`caseNum` AS isPaperAva, 
       A.`rowCaseType`, 
       A.`fullCaseNumber`, 
       A.`rowProcedure`, 
       B.`caseFullName`, 
       A.`rowCourt`, 
       A.`rowAmount`, 
       A.`rowResultTaken`, A.`rowStatus`, A.`rowIntrest` ,A.`DateOpen` ,A.`DateProccess`, A.`rowDateClose`, A.`rowJudgeTypeDate` 

FROM (SELECT * FROM `rowsall` WHERE `rowJudgeTypeName` LIKE '%@value1%' AND `RowNum` ='1' ) A 
INNER JOIN ( SELECT `id`,`caseFullName` FROM `casses_rows` ) B 
      ON A.`masterCaseId` = B.`id` 
LEFT JOIN (SELECT `caseNum` FROM `casedocs` GROUP BY `caseNum` ORDER BY NULL ) C 
      ON A.`fullCaseNumber` = C.`caseNum`

结果如我所愿,但问题是返回结果需要1分钟...

解释如下:

  id   select_type  table       type   possible_keys  key     key_len  ref  rows   Extra
  1    PRIMARY      <derived2>  ALL    NULL           NULL    NULL     NULL 121
  1    PRIMARY      <derived3>  ALL    NULL           NULL    NULL     NULL 24185  Using where; Using join buffer
  1    PRIMARY      <derived4>  ALL    NULL           NULL    NULL     NULL 343438
  4    DERIVED      casedocs    index  NULL           caseNum 62       NULL 768024 Using index
  3    DERIVED      casses_rows ALL    NULL           NULL    NULL     NULL 29872  
  2    DERIVED      rowsall     ref    RowNum         RowNum  4             6500   Using where

如您所见,我将表 3 分组以防止连接在结果中创建重复行 - 实际上,第三个连接是为了测试是否存在与案例对应的文档(将为 NULL)。

更多信息:

  • 如果我删除第三个连接,查询需要 1 秒
  • 如果我只执行第三个连接选择语句,它需要 0.003 秒
  • 分析查询时,“发送数据”占 99.9% 的时间。

知道为什么执行第三个连接需要这么长时间吗????

任务完成! 感谢@Turophile 和@Joel Coehoorn,新的测试结果约为 0.004 秒!!!

这是最后的查询:

SELECT DISTINCT A.`id` AS idRowCase, C.`caseNum` AS isPaperAva, A.`rowCaseType` ,  A.`fullCaseNumber` , A.`rowProcedure` , B.`caseFullName` , A.`rowCourt` , A.`rowAmount` , A.`rowResultTaken` , A.`rowStatus` , A.`rowIntrest` , A.`DateOpen` , A.`DateProccess` , A.`rowDateClose` , A.`rowJudgeTypeDate` 

FROM  `rowsall` A
INNER JOIN  `casses_rows` B ON A.`masterCaseId` = B.`id` 
LEFT JOIN  `casedocs` C ON A.`fullCaseNumber` = C.`caseNum` 
WHERE A.`rowJudgeTypeName` LIKE  '%@value1%'
AND A.`RowNum` =  '1'

最佳答案

我的建议是不要进行不必要的排序和分组。所以,像这样:

SELECT 
   A.`id` AS idRowCase, 
   C.`caseNum` AS isPaperAva, 
   A.`rowCaseType`, 
   A.`fullCaseNumber`, 
   A.`rowProcedure`, 
   B.`caseFullName`, 
   A.`rowCourt`, 
   A.`rowAmount`, 
   A.`rowResultTaken`, 
   A.`rowStatus`, 
   A.`rowIntrest`,
   A.`DateOpen` ,
   A.`DateProccess`, 
   A.`rowDateClose`, 
   A.`rowJudgeTypeDate` 

FROM `rowsall` AS A 
INNER JOIN `casses_rows` AS B 
      ON A.`masterCaseId` = B.`id` 
LEFT JOIN `casedocs` AS C 
      ON A.`fullCaseNumber` = C.`caseNum`
WHERE `rowJudgeTypeName` LIKE '%@value1%' 
AND   `RowNum` ='1' 

(如果 caseNum 不是唯一的,可能会返回不同的结果(多行))。

您还可以将 LEFT JOIN 变成子选择:

SELECT 
   A.`id` AS idRowCase, 
   A.`fullCaseNumber` AS isPaperAva, 
   A.`rowCaseType`, 
   A.`fullCaseNumber`, 
   A.`rowProcedure`, 
   B.`caseFullName`, 
   A.`rowCourt`, 
   A.`rowAmount`, 
   A.`rowResultTaken`, 
   A.`rowStatus`, 
   A.`rowIntrest`,
   A.`DateOpen` ,
   A.`DateProccess`, 
   A.`rowDateClose`, 
   A.`rowJudgeTypeDate` 

FROM `rowsall` AS A 
INNER JOIN `casses_rows` AS B 
      ON A.`masterCaseId` = B.`id` 
WHERE `rowJudgeTypeName` LIKE '%@value1%' 
AND   `RowNum` ='1' 
AND   A.`fullCaseNumber` in (SELECT `caseNum` FROM `casedocs` ) 

但这表明使用表 casedocs 有点多余 - 真的需要吗?

关于mysql - 添加第三个 LEFT JOIN 时查询速度很慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23379427/

相关文章:

python - Django 模板未呈现

SQL - 添加/禁用基于 Select 语句中的 bool 条件的 Where 子句 (ASP.net SQLDataSource)

MySql - 如何将存储的函数存储在表中?

mysql - 如何减去mysql where子句中的两列?

php - mysql更新语法中的columname可以是变量吗?

消息系统的mysql查询

mysql - 创建触发器以从一个数据库表插入到 PHPMYADMIN 中的不同数据库表中

sql - 如何将简单的 bool 语句转换为 SQL?

c# - LINQ - 加入 3 个表与分组和求和

sql - 我应该避免连接中的循环吗?