Excel 中动态 SQL 查询的性能问题

Posted

技术标签:

【中文标题】Excel 中动态 SQL 查询的性能问题【英文标题】:Performance Issue with dynamic SQL query in Excel 【发布时间】:2018-03-10 20:06:38 【问题描述】:

我想在 Excel 中针对 redshift/postgres 数据库创建一个动态 SQL 查询,以增强包含多列的元素的动态列表。

基本上,我希望能够将 ID 列表复制/键入到 excel 中,如下所示:

Id
------
AAC123
ABB203
AEF678
AEK232
BCE123
BFG304

理想情况下,SQL 查询将使用如下语句:

select * 
from table 
where ID in ('AAC123', 'ABB203', 'AEF678', 'AEK232', 'BCE123', 'BFG304')

我设法使用以下方法 https://exceleratorbi.com.au/pass-excel-parameter-power-query/ 在 Power Query 中创建了一个与一个属性一起使用的参数

select * 
from table 
where ID = Parameter

当我将= ParameterIN Parameter 交换时,出现以下错误:

表达式错误标记 RightParen 预期

当我改用 IN (Parameter) 时,我得到了同样的错误。

我设法通过在电源查询中将两个表与内部联接合并来创建解决方法。不幸的是,redshift / postgres 中的表有 1000 万行,刷新 25-100 个项目的列表通常需要 5 分钟以上。没有动态 SQL 的相同查询只需要 15 秒。

有没有人建议我需要做些什么不同的事情?

【问题讨论】:

可能,您的表中缺少一些索引? 什么是参数?一张桌子?逗号分隔列表?一个字符串? @NicoHaase - 不幸的是,我对表格的唯一引用是字符串列。 @Parfait我使用了以下方法exceleratorbi.com.au/pass-excel-parameter-power-query @Andreas 向您的数据库添加索引与您稍后在应用程序中访问数据的方式无关。 【参考方案1】:

ID 表加载到查询编辑器中并将其转换为列表(转换> 转换为列表)。我假设你的表名是Table1

在您的查询表上,选择任何单个 ID 值进行过滤。查询编辑器应该生成一个步骤,其代码类似于:

= Table.SelectRows(Source, each ([ID] = "AAC123"))

取而代之,让我们将选择条件替换为使用Table1

= Table.SelectRows(Source, each List.Contains(Table1, [ID]))

如果您在右侧的 Applied Steps 部分中右键单击此步骤并选择 View Native Query,那么您应该会看到 SQL 查询有一个 WHERE 子句,就像您在您的帖子中一样。

这个“本机查询”是被发送回服务器的,所以这应该会提高性能。


注意:您不一定要先转换为列表。如果您不将其转换为列表,那么您的过滤步骤将如下所示(您使用列名):

= Table.SelectRows(Source, each List.Contains(Table1[ID], [ID]))

编辑:由于您在连接中使用 SQL 连接字符串,您可以在此字符串中的 WHERE 语句中包含 ID 列表:

query: = Odbc.Query("dsn=Redshift",
                    "select ID, column_A, column_B
                     from redshift.db.info
                     where ID in (" & Text.Combine(Table1[ID], ",") & ")")

Text.Combine 函数连接 ID 列。)

【讨论】:

非常感谢。有效。不幸的是,它仍然很慢。 非常感谢。有效。不幸的是,它仍然很慢。当我单击刷新所有数据时,仅连接到 redshift 至少需要 2 分钟(等待 DSN = Redshift)然后它加载了 508 行但继续运行(运行后台查询)。如果我在没有嵌入参数/列表的情况下运行相同的查询,则刷新需要 5 秒,并且要查找的 ID 数量相似(25 个 ID)。有什么想法或建议吗? 实际上它从来没有结束刷新背景所以我没有看到任何结果。 查询中还有其他步骤吗?有时,查询编辑器会尝试将过多的内容折叠到它传递回数据库的查询中。您能否验证仅加载数据(不执行其他操作)加载列表和硬编码 ID 值之间存在很大差异? 我有两个问题。 1个查询称为输入,步骤如下: = Excel.CurrentWorkbook()[Name="Input"][Content] = Table.TransformColumnTypes(Source,"ID", type text) 然后我有实际的SQL 连接/查询: = Odbc.Query("dsn=Redshift", "select ID, column_A, column_B from redshift.db.info") = Table.SelectRows(Source, each List.Contains(Input[ID], [ID ])) 这是你想要的设置方式吗?

以上是关于Excel 中动态 SQL 查询的性能问题的主要内容,如果未能解决你的问题,请参考以下文章

以另一种方式提高动态 SQL 查询性能或过滤记录

SQL Server-聚焦sp_executesql执行动态SQL查询性能真的比exec好?

SQL Server-聚焦sp_executesql执行动态SQL查询性能真的比exec好?

SQL查询中年龄计算的性能

动态性能视图

连接查询的休眠性能问题