在工作中开发新查询时,我编写了它并在SQL查询分析器中对其进行了分析.查询在没有任何表扫描的情况下表现非常好但是当我将其封装在存储过程中时,性能非常糟糕.当我查看执行计划时,我可以看到SQL Server选择了一个不同的计划,使用表扫描而不是TableB上的索引查找(我被迫混淆了表和列名,但没有查询逻辑已经改变).
这是查询
SELECT
DATEADD(dd, 0, DATEDIFF(dd, 0, TableA.Created)) AS Day,
DATEPART(hh, TableA.Created) AS [Hour],
SUM(TableB.Quantity) AS Quantity,
SUM(TableB.Amount) AS Amount
FROM
TableA
INNER JOIN TableB ON TableA.BID = TableB.ID
WHERE
(TableA.ShopId = @ShopId)
GROUP BY
DATEADD(dd, 0, DATEDIFF(dd, 0, TableA.Created)),
DATEPART(hh, TableA.Created)
ORDER BY
DATEPART(hh, TableA.Created)
Run Code Online (Sandbox Code Playgroud)
当我运行查询"raw"时,我得到以下跟踪统计信息
Event Class Duration CPU Reads Writes SQL:StmtCompleted 75 41 7 0
当我使用以下命令将查询作为存储过程运行时
DECLARE @ShopId int
SELECT @ShopId = 1
EXEC spStats_GetSalesStatsByHour @ShopId
Run Code Online (Sandbox Code Playgroud)
我得到以下跟踪统计数据
Event Class Duration CPU Reads Writes SQL:StmtCompleted 222 10 …
关于SQL中语句的执行顺序,以下性能是否有明显区别?
SELECT * FROM Persons
WHERE UserType = 'Manager' AND LastName IN ('Hansen','Pettersen')
Run Code Online (Sandbox Code Playgroud)
和:
SELECT * FROM Persons
WHERE LastName IN ('Hansen','Pettersen') AND UserType = 'Manager'
Run Code Online (Sandbox Code Playgroud)
如果有任何差异,是否可能有一个链接等,你可以在哪里可以了解更多相关信息?
万分感谢,
凯尔
在我的一个查询中,有一个insert数据到临时表中.查看查询计划,它显示临时表中的实际插入占用了54%(只是将数据插入临时表).但是,没有行插入临时表.
为什么在没有插入行时计划显示非零值?
我的查询:
EXPLAIN EXTENDED SELECT `artwork`.`id` , `artwork`.`added`
FROM `artwork`
ORDER BY `artwork`.`added` DESC
LIMIT 0 , 6
Run Code Online (Sandbox Code Playgroud)
当我在"添加"上添加索引以避免使用filesort和使用index而不是解释的输出来自
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE artwork ALL NULL NULL NULL NULL 302 100.00 Using filesort
Run Code Online (Sandbox Code Playgroud)
至
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE artwork index NULL added 4 NULL 6 5033.33
Run Code Online (Sandbox Code Playgroud)
而且我担心过滤的上升大约是4,100 - 我在Google上找不到什么filtered意思
正如标题所述,我不明白为什么sp_executeSQL会生成与从Sql Management Studio运行查询完全不同的执行计划.
从SQL管理工作室运行时,我的查询将需要3秒钟,因为通过sp_executeSQL在管理工作室中运行的查询将花费5分钟.
我已经更新了统计数据,并查看了索引,但事实上仍然存在这样的事实:sp_executeSQL的执行计划比直接从我的管理工作室运行sql更糟糕.
所以这是我的问题:为什么执行计划在以这两种不同方式运行查询之间会有很大差异?
谢谢
我正在尝试分析Oracle数据库中的查询执行计划.我已经设定
alter system set statistics_level = all;
Run Code Online (Sandbox Code Playgroud)
这样我就可以将估计的基数和时间与实际的基数和时间进行比较.现在,我正在运行此语句以显示该信息.
select * from table(dbms_xplan.display_cursor(
sql_id => '6dt9vvx9gmd1x',
cursor_child_no => 2,
FORMAT => 'ALLSTATS LAST'));
Run Code Online (Sandbox Code Playgroud)
但我不断收到这条消息
NOTE: cannot fetch plan for SQL_ID: 6dt9vvx9gmd1x, CHILD_NUMBER: 2
Please verify value of SQL_ID and CHILD_NUMBER;
It could also be that the plan is no longer in cursor cache (check
v$sql_plan)
Run Code Online (Sandbox Code Playgroud)
在CHILD_NUMBER正在执行的查询时是正确的.此外,当我dbms_xplan.display_cursor在查询的同时运行时,我得到了实际的计划.但是我的JDBC连接PreparedStatement在执行后立即关闭,所以也许这就是执行计划从中消失的原因v$sql_plan.
我是否出错了,或者如何在执行后分析估计/实际值?
其中一个查询(如下所示)需要90秒以上才能执行.它从一个相当大的表LogMessage返回~500行.如果ESCAPE N'~'从查询中删除它,它会在几秒钟内执行.同样,如果TOP (1000)删除它,它会在几秒钟内执行.查询计划Key Lookup (Clustered) PK_LogMessage, Index Scan (NonClustered) IX_LogMessage and Nested Loops (Inner Join)在第一种情况下显示.当从句ESCAPE N'~'或TOP (1000)移除查询计划的变化,以及Clustered Index Scan (Clustered) PK_LogMessage.虽然我们正在寻找添加更多索引(可能在ApplicationName上),但我们想了解当前的情况.
正在生成查询Entity Framework,以防您想知道为什么以这种方式编写.实际查询也更复杂,但这是表现出相同行为的最短版本.
查询:
SELECT TOP (1000)
[Project1].[MessageID] AS [MessageID],
[Project1].[TimeGenerated] AS [TimeGenerated],
[Project1].[SystemName] AS [SystemName],
[Project1].[ApplicationName] AS [ApplicationName]
FROM
(
SELECT
[Project1].[MessageID] AS [MessageID],
[Project1].[TimeGenerated] AS [TimeGenerated],
[Project1].[SystemName] AS [SystemName],
[Project1].[ApplicationName] AS [ApplicationName]
FROM
(
SELECT
[Extent1].[MessageID] AS [MessageID],
[Extent1].[TimeGenerated] AS [TimeGenerated],
[Extent1].[SystemName] AS [SystemName], …Run Code Online (Sandbox Code Playgroud) sql sql-server performance sql-server-2008-r2 sql-execution-plan
Nhibernate探查器显示有关查询计划的大量错误消息:
不同的参数大小会导致查询计划缓存使用效率低下
它还会引导您在http://nhprof.com/Learn/Alerts/UncachedQueryPlan中进行解释,并prepare_sql = true在构建会话时警告您使用参数.我这样做是流利的:
.ExposeConfiguration(configuration => configuration
.SetProperty("current_session_context_class", "thread_static")
.SetProperty("prepare_sql", "true")
.SetProperty("generate_statistics", "true")
)
Run Code Online (Sandbox Code Playgroud)
但似乎它没有工作,因为错误消息仍然存在.这是对OracleClientConfiguration的限制还是我做错了?
编辑提供有关此内容的更多信息......
在我的存储库中,我这样做
session.Query<TEntity>.Where(predicate).ToList();
Run Code Online (Sandbox Code Playgroud)
这就是电话
var value = ParameterRepository.First(p => (p.Pipeline.Id == pipelineId && p.Name == name));
Run Code Online (Sandbox Code Playgroud)
例如,这些是从此调用生成的两个SQL,并且nhibernate profiler显示为"不同的参数大小导致查询计划缓存使用效率低下"
select GUID1_12_,
PARAMETER2_12_,
PARAMETER3_12_,
GUID4_12_
from (select pipelineex0_.GUID_PIPELINE_EXEC_PARAMETER as GUID1_12_,
pipelineex0_.PARAMETER_NAME as PARAMETER2_12_,
pipelineex0_.PARAMETER_VALUE as PARAMETER3_12_,
pipelineex0_.GUID_PIPELINE_TRACKING as GUID4_12_
from FCT_PIPELINE_EXEC_PARAMETER pipelineex0_
where pipelineex0_.GUID_PIPELINE_TRACKING = 'A5916E73CF1E406DA26F65C24BFBF694' /* :p0 */
and pipelineex0_.PARAMETER_NAME = 'lid' /* :p1 */)
where rownum <= 1 /* …Run Code Online (Sandbox Code Playgroud) sqlite> explain query plan select max(utc_time) from RequestLog;
0|0|0|SEARCH TABLE RequestLog USING COVERING INDEX key (~1 rows) # very fast
sqlite> explain query plan select min(utc_time) from RequestLog;
0|0|0|SEARCH TABLE RequestLog USING COVERING INDEX key (~1 rows) # very fast
sqlite> explain query plan select min(utc_time), max(utc_time) from RequestLog;
0|0|0|SCAN TABLE RequestLog (~8768261 rows) # will be very very slow
Run Code Online (Sandbox Code Playgroud)
虽然我使用min和max独立,它完美的作品.但是,sqlite会因为某些原因选择min和max一起时"忘记"索引.有没有我可以做的配置(我Analyze已经使用过,它不起作用)?或者这种行为有什么解释吗?
sqlite> .schema
CREATE TABLE FixLog(
app_id text, __key__id …Run Code Online (Sandbox Code Playgroud) 当我们在Oracle中执行任何sql语句时,会为该sql语句分配一个哈希值并将其存储到库缓存中.因此,稍后,如果另一个用户请求相同的查询,则Oracle会找到哈希值并执行相同的执行计划.但是,我对哈希值有一个疑问.我的意思是,如何生成哈希值?我的意思是,Oracle服务器是否使用某些算法,或者只是将sql字符串转换为某个数值.
从那时起,我正在阅读Pro Oracle SQL书籍,上面写着,
select * from employees where department_id = 60;
SELECT * FROM EMPLOYEES WHERE DEPARTMENT_ID = 60;
select /* a_comment */ * from employees where department_id = 60;
Run Code Online (Sandbox Code Playgroud)
将返回不同的哈希值,因为当执行sql语句时,Oracle首先将字符串转换为哈希值.但是,当我尝试这个时,它返回相同的哈希值.
SQL> select * from boats where bid=10;
no rows selected
Execution Plan
----------------------------------------------------------
Plan hash value: 2799518614
-------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 16 …Run Code Online (Sandbox Code Playgroud) sql ×5
sql-server ×4
oracle ×3
t-sql ×3
performance ×2
mysql ×1
nhibernate ×1
oracle11g ×1
sqlite ×1