相同的查询 - 查询存储区

时间:2018-01-08 16:28:46

标签: sql sql-server entity-framework azure-sql-database sql-query-store

问题:

我们使用实体框架(6.21)作为我们的ORM经理。 我们的数据库是Azure Sql Database。

因为某些参数化查询(在我们的应用程序中经常使用)在某些输入上很慢(在某些输入上,它在其他输入上运行60秒,运行0.4秒)

我们开始使用MS SQL Management Studio中的QueryStore和QueryStore资源管理器( MSSMS - >对象资源管理器 - >查询存储)调查这些查询。

我们发现,QueryStore将两个相同的(相同的sql查询,但不同的参数 - 甚至没有存储参数)查询存储为不同的查询(具有不同的query_id)。 通过不同的查询我的意思是表中的不同行 sys.query_store_query)。

我通过查看QueryStore表来检查这个:

    SELECT 
     qStore.query_id,
     qStore.query_text_id,
     queryTextStore.query_sql_text
     ROW_NUMBER() OVER(PARTITION BY query_sql_text ORDER BY query_sql_text ASC) AS rn 
    FROM 
    sys.query_store_query qStore
    INNER JOIN 
    sys.query_store_query_text queryTextStore 
    ON qStore.query_text_id = queryTextStore.query_text_id

Screenshot from MSSSM

我无法在MSSMS中轻松比较这些查询的计划,因为每个查询都有自己的关联计划。

预期行为 我假设每次后续运行具有不同参数的相同查询都会导致:

1 /重新使用现有计划 或

2 /基于传递的params值创建另一个计划...

示例:

查询看起来像这样(实际上查询要复杂得多,因为它们是由EntityFramework 生成的):

SELECT * FROM tbl WHERE a = @__plinq__

并且它的两次后续运行(使用不同的参数)将导致sys.query_store_query中的两行。

问题:

如何使Azure保存与同一查询相同的查询?或者我错过了什么或这是预期的行为?

或者更一般地说,如果数据库查询是由Entity Framework生成的,那么如何调优它们?

SQL Server查询存储如何将两个查询视为相同或不同?

修改1:更新

基于@PeterB评论(Adding a query hint when calling Table-Valued Function),我们能够通过对某些参数值的慢查询来解决我们的问题(我们在有问题的查询中添加了提示"recompile")。

基于@GrantFritchey提示我检查了context_settings,但query_store表中仍有多行具有相同的query_sql_text和相同的context_settings_id但具有不同的query_id

所以我们仍然想知道SQL Server查询存储如何考虑相同或不同的两个查询?

1 个答案:

答案 0 :(得分:2)

对于不同的查询条目,Query Store用于查询的键包括:

  • query_text_id,
  • context_settings_id,
  • object_id,
  • batch_sql_handle,
  • query_parameterization_type

如果查询中的任何一个不同,它将在查询表中生成一个新条目。请注意,仅为引用临时表的查询填充batch_sql_handle。 因此,您可以检查列出的查询中哪些值不同。

目前,没有任何设置可以控制Query Store聚合查询的方式。将它们视为相同的唯一方法是更改​​工作负载,以便上面列出的字段匹配。但也许更好的方法是你编写自己的报告查询,根据你的需要汇总查询及其统计数据。