在SQL查询中获得更好的性能。

huangapple go评论59阅读模式
英文:

better performance on sql query

问题

SELECT 
  DISTINCT A_OMSCHRIJVING, 
  t1.LK_CODE, 
  t1.LK_KAMER_FK 
FROM 
  (SELECT 
    LK_ID, 
    LK_CODE, 
    LK_KAMER_FK 
  FROM 
    Lokaal
  WHERE 
    LK_ID IN (
      11, 13, 15, 16, 180, 183, 184, 185, 186, 
      189, 190, 191, 192, 195, 196, 198, 199, 
      200, 202, 206, 210, 211, 212, 213, 278, 
      282, 286, 287, 290, 291, 293, 298, 302, 
      303, 309, 310, 346, 367, 368, 382, 387, 
      540, 542, 543, 549, 551, 554, 555
    )
  ) AS t1
  INNER JOIN Lokaal LokaalAll ON (
    LokaalAll.LK_KAMER_FK = t1.LK_KAMER_FK
  ) 
  INNER JOIN agendalesdata ON (ALD_LOKAAL_FK = t1.LK_ID) 
  INNER JOIN agendapunt ON (APU_agendalesdata_FK = ALD_ID) 
  INNER JOIN agendaitems ON (AIT_AGENDAPUNT_FK = APU_ID) 
  INNER JOIN agenda ON (
    AIT_AGENDA_FK = A_ID 
    AND A_TYPEAGENDA = 6
  ) 
WHERE 
  (APU_TOT >= '2023-04-27 14:45:00') 
  AND (APU_VAN < '2023-04-27 15:35:00') 
ORDER BY 
  AIT_ID
英文:

I've been trying to rewrite the following query, because it's taking too long. I tried to rewrite it using Common Table Expressions, but still taking long or records are not equal.

This is the query I need to make it better performance.

SELECT 
  DISTINCT A_OMSCHRIJVING, 
  LokaalAll.LK_CODE, 
  LokaalAll.LK_KAMER_FK 
FROM 
  Lokaal LokaalOri 
  inner join lokaal LokaalAll on (
    LokaalAll.LK_KAMER_FK = LokaalOri.LK_KAMER_FK
  ) 
  inner join agendalesdata on (ALD_LOKAAL_FK = LokaalAll.LK_ID) 
  Inner join agendapunt on (APU_agendalesdata_FK = ALD_ID) 
  inner join agendaitems on (AIT_AGENDAPUNT_FK = APU_ID) 
  inner join agenda on (
    AIT_AGENDA_FK = A_ID 
    and A_TYPEAGENDA = 6
  ) 
WHERE 
  (
    LokaalOri.LK_ID in (
      11, 13, 15, 16, 180, 183, 184, 185, 186, 
      189, 190, 191, 192, 195, 196, 198, 199, 
      200, 202, 206, 210, 211, 212, 213, 278, 
      282, 286, 287, 290, 291, 293, 298, 302, 
      303, 309, 310, 346, 367, 368, 382, 387, 
      540, 542, 543, 549, 551, 554, 555
    )
  )  
  AND (APU_TOT &gt;= &#39;2023-04-27 14:45:00&#39;) 
  AND (APU_VAN &lt; &#39;2023-04-27 15:35:00&#39;) 
ORDER BY 
 AIT_ID

I think the performance is hit on this logic.

  Lokaal LokaalOri 
  inner join lokaal LokaalAll on (
    LokaalAll.LK_KAMER_FK = LokaalOri.LK_KAMER_FK
  ) 

I tried the following query

WITH t1 as ( select
  LK_ID, 
  LK_CODE, 
  LK_KAMER_FK 
FROM 
  Lokaal
  WHERE 
  (
    LK_ID in (
      11, 13, 15, 16, 180, 183, 184, 185, 186, 
      189, 190, 191, 192, 195, 196, 198, 199, 
      200, 202, 206, 210, 211, 212, 213, 278, 
      282, 286, 287, 290, 291, 293, 298, 302, 
      303, 309, 310, 346, 367, 368, 382, 387, 
      540, 542, 543, 549, 551, 554, 555
    )
  ) 
)
 select  A_OMSCHRIJVING, 
  t1.LK_CODE, 
  t1.LK_KAMER_FK from t1
  inner join lokaal LokaalAll on (
    LokaalAll.LK_KAMER_FK = t1.LK_KAMER_FK
  ) 
    inner join agendalesdata on (ALD_LOKAAL_FK = t1.LK_ID) 
      Inner join agendapunt on (APU_agendalesdata_FK = ALD_ID)     
  inner join agendaitems on (AIT_AGENDAPUNT_FK = APU_ID) 
  inner join agenda on (
    AIT_AGENDA_FK = A_ID 
    and A_TYPEAGENDA = 6
  ) 
  WHERE 

   (APU_TOT &gt;= &#39;2023-04-27 14:45:00&#39;) 
  AND (APU_VAN &lt; &#39;2023-04-27 15:35:00&#39;)  
ORDER BY 
  AIT_ID

But not same records are returned.

PS. Common Table Expressions are not obligated to be used.

答案1

得分: 1

以下是您提供的内容的中文翻译:

首先,在查询中,您应始终通过使用"表名.列名"或"别名.列名"来标明列,以便用户知道列来自哪里。

接下来,编辑您现有的帖子并列出表结构。我们不知道哪个外键与其他表的主键连接在一起。尽管如此,我刚刚强制将别名应用于表,并可能在连接子句中应用了错误的"别名.列名",这将导致查询失败。

尽管如此,当您重新编辑帖子并提供表结构(哪些表具有哪些列)后,我可以提供更多帮助。

现在回到查询。您两次使用了"Lokaal"表,在"LK_KAMER_FK"上连接自身,这可能导致查询产生笛卡尔积。请查看以下示例数据。

Lokaal
ID   LK_KAMER_FK  SomeOtherField
1    A            B
2    B            B
3    A            X
4    A            Y
5    B            W
6    A            Z
7    B            R

尽管上述示例中有7条记录,但通过在"LK_KAMER_FK"上连接,实际上得到了以下结果:

LokaalOri ID    LokaalOri LK_KAMER_FK     LokaalAll ID   LokaalAll LK_KAMER_FK   LokaalAll SomeOtherField
1               A                         1              A                       B
1               A                         3              A                       X
1               A                         4              A                       Y
1               A                         6              A                       Z
接下来,在"LokaalOri ID"等于3时(下一个LK_KAMER_FK的行),结果如下:
3               A                         1              A                       B
3               A                         3              A                       X
3               A                         4              A                       Y
3               A                         6              A                       Z
再次移动到ID#4
4               A                         1              A                       B
4               A                         3              A                       X
4               A                         4              A                       Y
4               A                         6              A                       Z
还有6
6               A                         1              A                       B
6               A                         3              A                       X
6               A                         4              A                       Y
6               A                         6              A                       Z

甚至在您到达"LK_KAMER_FK"的值为"B"之前,就已经出现了这种情况。这被称为笛卡尔积结果,非常糟糕。

因此,请摆脱它。只需使用一个表并直接连接它。

以下是查询:

SELECT DISTINCT 
	A_OMSCHRIJVING, 
	L.LK_CODE, 
	L.LK_KAMER_FK 
FROM 
	Lokaal L 
	INNER JOIN agendalesdata Ag
		ON L.LK_ID = Ag.ALD_LOKAAL_FK
	INNER JOIN agendapunt Ap
		ON Ag.ALD_ID = Ap.APU_agendalesdata_FK
	INNER JOIN agendaitems Ai
		ON Ap.APU_ID = Ai.AIT_AGENDAPUNT_FK
	INNER JOIN agenda Ag2
		ON Ai.AIT_AGENDA_FK = Ag2.A_ID 
		AND Ag2.A_TYPEAGENDA = 6
WHERE 
	L.LK_ID IN 
	(
		11, 13, 15, 16, 180, 183, 184, 185, 186, 
		189, 190, 191, 192, 195, 196, 198, 199, 
		200, 202, 206, 210, 211, 212, 213, 278, 
		282, 286, 287, 290, 291, 293, 298, 302, 
		303, 309, 310, 346, 367, 368, 382, 387, 
		540, 542, 543, 549, 551, 554, 555
	)
	AND Ap.APU_TOT >= '2023-04-27 14:45:00'
	AND Ap.APU_VAN < '2023-04-27 15:35:00'
ORDER BY 
	Ai.AIT_ID

同样,上述查询将失败,因为我们不知道哪些列实际与哪个表相关联。在编辑后,具有适当索引可以进一步改善性能。

英文:

First, you should always qualify the columns in your query by doing table.column or alias.column so users know which columns come from where.

Next, edit your existing post and list the table structures. We have no idea which foreign key joins to the other tables primary key. Having said that, I just forced aliases to the tables and probably applied the incorrect alias.column in the JOIN clauses which will make the query fail.

Having said that, I can offer more after getting the table structures (which tables have which columns) when you re-edit your post.

Now back to the query. You are using the Lokaal table twice, joining on itself on the LK_KAMER_FK which is probably killing your query with a Cartesian product. Take a look at the following sample data.

Lokaal
ID   LK_KAMER_FK  SomeOtherField
1    A            B
2    B            B
3    A            X
4    A            Y
5    B            W
6    A            Z
7    B            R

Even though you have 7 records in the above sample, by joining on the LK_KAMER_FK, you are actually getting

LokaalOri ID    LokaalOri LK_KAMER_FK     LokaalAll ID   LokaalAll LK_KAMER_FK   LokaalAll SomeOtherField
1               A                         1              A                       B
1               A                         3              A                       X
1               A                         4              A                       Y
1               A                         6              A                       Z
Now, the next iteration on the LokaalOri ID = 3 (next in line for LK_KAMER_FK) now results with
3               A                         1              A                       B
3               A                         3              A                       X
3               A                         4              A                       Y
3               A                         6              A                       Z
and again moving to ID #4
4               A                         1              A                       B
4               A                         3              A                       X
4               A                         4              A                       Y
4               A                         6              A                       Z
and 6 
6               A                         1              A                       B
6               A                         3              A                       X
6               A                         4              A                       Y
6               A                         6              A                       Z

even before you get to the "B" values of LK_KAMER_FK. This is known as a Cartesian result -- very bad.

Now, consider if you have 500 records with an LK_KAMER_FK of "A". You have just killed your machine's memory.
So, get rid of it. Just use the one and join from that directly.

SELECT DISTINCT 
		A_OMSCHRIJVING, 
		L.LK_CODE, 
		L.LK_KAMER_FK 
	FROM 
		Lokaal L 
			inner join agendalesdata Ag
				on L.LK_ID = Ag.ALD_LOKAAL_FK
				Inner join agendapunt Ap
					on Ag.ALD_ID = Ap.APU_agendalesdata_FK
					inner join agendaitems Ai
						on Ap.APU_ID = Ai.AIT_AGENDAPUNT_FK
						inner join agenda Ag2
							on Ai.AIT_AGENDA_FK = Ag2.A_ID 
							and Ag2.A_TYPEAGENDA = 6
	WHERE 
			L.LK_ID in 
			(
				11, 13, 15, 16, 180, 183, 184, 185, 186, 
				189, 190, 191, 192, 195, 196, 198, 199, 
				200, 202, 206, 210, 211, 212, 213, 278, 
				282, 286, 287, 290, 291, 293, 298, 302, 
				303, 309, 310, 346, 367, 368, 382, 387, 
				540, 542, 543, 549, 551, 554, 555
			)
		AND Ap.APU_TOT &gt;= &#39;2023-04-27 14:45:00&#39;
		AND Ap.APU_VAN &lt; &#39;2023-04-27 15:35:00&#39;
	ORDER BY 
		Ai.AIT_ID

Again, the above will fail as we have no idea which columns are really associated with which table. And having proper indexes after your edit can add additional improvement.

huangapple
  • 本文由 发表于 2023年5月10日 18:38:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/76217410.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定