我遇到了这个Postgres问题,如果我在查询字符串上使用参数vs硬编码它的相同查询需要很长时间才能执行.列名是'media_type',它是VARCHAR(20).我正在使用Symfony2和Doctrine2 ORM从PHP运行这些查询,并且该表有大约1.000.000条记录.
我的查询有问题吗?它可能是Postgres配置问题吗?
1 - media_type的硬编码值
duration: 5.365 ms parse pdo_stmt_00000001: SELECT id,site_id FROM item where media_type = 'Collection' AND enabled = 'true' AND site_id = $1 AND user_id = $2 ORDER BY id DESC LIMIT $3 OFFSET $4
duration: 0.142 ms bind pdo_stmt_00000001: SELECT id,site_id FROM item where media_type = 'Collection' AND enabled = 'true' AND site_id = $1 AND user_id = $2 ORDER BY id DESC LIMIT $3 OFFSET $4
parameters: $1 = '1', $2 = '1', $3 …Run Code Online (Sandbox Code Playgroud) postgresql sql-execution-plan symfony doctrine-orm postgresql-9.1
我的最终目标是从缓存的执行计划中自动提取所有引用的列。这将帮助我们跟踪我们预定的 SSRS 报告集使用的所有列。
感兴趣的 XML 数据如下所示:
<ColumnReference Database="[AdventureWorksDW2012]" Schema="[dbo]" Table="[DimCustomer]" Alias="[dC]" Column="HouseOwnerFlag" />
Run Code Online (Sandbox Code Playgroud)
我想在表中存储数据库、架构、表、别名和列值。
但是,为了概念验证,我进行了一个简单的查询,并将完整执行计划的以下部分复制到下面的 TSQL 代码中:
DECLARE @myDoc xml;
SET @myDoc = '<ShowPlanXML xmlns="http://schemas.microsoft.com/sqlserver/2004/07/showplan" Version="1.2" Build="11.0.3381.0" TEST="1">
<BatchSequence>
<Batch>
<Statements>
<StmtSimple StatementText="SELECT ... 
" StatementId="1" StatementCompId="1" ThereIsMoreHere="..." >
<StatementSetOptions QUOTED_IDENTIFIER="true" ARITHABORT="true" ThereIsMoreHere="..." />
</StmtSimple>
</Statements>
</Batch>
</BatchSequence>
</ShowPlanXML>';
SELECT StatementId = @myDoc.value('(/ShowPlanXML/BatchSequence/Batch/Statements/StmtSimple/@StatementId)[1]', 'int');
SELECT StatementId = @myDoc.value('(/ShowPlanXML/@TEST)[1]', 'int');
Run Code Online (Sandbox Code Playgroud)
两个 SELECT 语句都返回 NULL。这里有什么问题?我觉得我正在慢慢失明。这是针对 SQL Server 2012 SP1 Developers 版本执行的。
在 PostgreSQL 中,我的表上的日期字段有一个索引tickets。当我将字段与 进行比较时now(),查询非常有效:
# explain analyze select count(1) as count from tickets where updated_at > now();
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------------------
Aggregate (cost=90.64..90.66 rows=1 width=0) (actual time=33.238..33.238 rows=1 loops=1)
-> Index Scan using tickets_updated_at_idx on tickets (cost=0.01..90.27 rows=74 width=0) (actual time=0.016..29.318 rows=40250 loops=1)
Index Cond: (updated_at > now())
Total runtime: 33.271 ms
Run Code Online (Sandbox Code Playgroud)
now()如果我尝试将其与负间隔进行比较,它会走下坡路并使用位图堆扫描。
# explain analyze select count(1) as count from tickets where updated_at > (now() - '24 hours'::interval);
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------------------
Aggregate (cost=180450.15..180450.17 rows=1 width=0) …Run Code Online (Sandbox Code Playgroud) sql postgresql indexing sql-execution-plan postgresql-performance
PostgreSQL 是否像存储过程一样缓存视图的执行计划?
根据这个Oracle 文档,我可以假设优化器推迟了硬解析,并且直到第一次执行准备好的语句时才生成执行计划:
“答案是一种称为绑定窥视的现象。早些时候,当您在绑定变量值设置为“NY”的情况下运行该查询时,优化器必须第一次进行硬解析,并且在这样做时它会窥视绑定变量看看它被赋予了什么价值。”
但是,当对带有绑定参数的准备好的语句执行 EXPLAIN PLAN 时,我们会得到一个执行计划。马库斯·维南德 (Markus Winand)在他的网站上表示:
“使用绑定参数时,优化器没有可用的具体值来确定它们的频率。然后它只是假设均匀分布并始终获得相同的行计数估计和成本值。最后,它将始终选择相同的执行计划。 ”
哪一个是真的?当使用均匀分布值模型准备语句时是否生成执行计划,或者是否将硬解析推迟到第一次执行时间。
在MySQL的5.7文档状态:
该
filtered列指示将由表条件过滤的表行的估计百分比。也就是说,rows显示估计的检查行数并rows × filtered / 100显示将与先前表连接的行数。
为了更好地理解这一点,我在使用MySQL Sakila 示例数据库的查询中进行了尝试。有问题的表具有以下结构:
mysql> SHOW CREATE TABLE film \G
*************************** 1. row ***************************
Table: film
Create Table: CREATE TABLE `film` (
`film_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(255) NOT NULL,
`description` text,
`release_year` year(4) DEFAULT NULL,
`language_id` tinyint(3) unsigned NOT NULL,
`original_language_id` tinyint(3) unsigned DEFAULT NULL,
`rental_duration` tinyint(3) unsigned NOT NULL DEFAULT '3',
`rental_rate` decimal(4,2) NOT NULL DEFAULT '4.99',
`length` smallint(5) unsigned DEFAULT …Run Code Online (Sandbox Code Playgroud) 我正在做一个概念证明,我正在尝试一种奇怪的行为.我有一个由日期字段按范围分区的表,如果我设置固定日期或由SYSDATE创建的日期,查询的成本会发生很大变化.
这些是解释计划:
SQL> SELECT *
2 FROM TP_TEST_ELEMENTO_TRAZABLE ET
3 WHERE ET.FEC_RECEPCION
4 BETWEEN TRUNC(SYSDATE-2) AND TRUNC(SYSDATE-1)
5 ;
5109 filas seleccionadas.
Plan de Ejecuci¾n
----------------------------------------------------------
Plan hash value: 1151442660
------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 5008 | 85136 | 4504 (8)| 00:00:55 | | |
|* 1 | FILTER | | | | | | | |
| …Run Code Online (Sandbox Code Playgroud) 我只是想了解 SparkSQL (2.4) 中生成的查询计划。我有以下查询及其相应的查询计划(如下)。(该查询只是一个测试查询)。
create temporary view tab_in as
select distinct
mth_id
from tgt_tbl;
select /*+ BROADCAST(c) */
a.mth_id,
a.qtr_id,
a.prod_id,
a.sale_date
from my_table a
left anti join tab_in c
on a.mth_id = c.mth_id;
Run Code Online (Sandbox Code Playgroud)
解释一下计划:
+- *(3) Project [mth_id#652, qtr_id#653, prod_id#655, sale_dt#656]
+- *(3) BroadcastHashJoin [mth_id#652], [mth_id#867], LeftAnti, BuildRight
:- *(3) Project [mth_id#652, qtr_id#653, sale_dt#656, prod_id#655]
: +- *(3) Filescan parquet test_db.my_table[mth_id#652, qtr_id#653, prod_id#655, sale_dt#656] Batched: true, Format: Parquet, Location: CatalogFileIndex[s3://test-data/my_table/0], PartitionCount: 1, PartitionFilters: [], PushedFilters: [], ReadSchema ......
+- …Run Code Online (Sandbox Code Playgroud) 我已经读过连接比子查询更好.
但
EXPLAIN QUERY PLAN
SELECT Queue.Id, NULL
FROM Queue
INNER JOIN LastQueue
ON Queue.Id=LastQueue.Id
Run Code Online (Sandbox Code Playgroud)
给
Array
(
[0] => Array
(
[selectid] => 0
[order] => 0
[from] => 0
[detail] => SCAN TABLE Queue (~1000000 rows)
)
[1] => Array
(
[selectid] => 0
[order] => 1
[from] => 1
[detail] => SEARCH TABLE LastQueue USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)
)
)
Run Code Online (Sandbox Code Playgroud)
而
EXPLAIN QUERY PLAN
SELECT Queue.Id, NULL
FROM Queue
WHERE (SELECT 1 FROM LastQueue …Run Code Online (Sandbox Code Playgroud) 在SQL Server 2008中,我已添加OPTION (MAXDOP 4)到查询中。
但是,在估计的执行计划中没有“平行”步骤。
这是否意味着即使我说“ MAXDOP 4” ,SQL Server也不选择不并行执行查询?
如何强制SQL Server使用并行性?
sql ×4
postgresql ×3
explain ×2
oracle ×2
sql-server ×2
t-sql ×2
caching ×1
database ×1
doctrine-orm ×1
indexing ×1
mysql ×1
optimization ×1
sqlite ×1
symfony ×1
xml ×1