我试图对一张大表进行分区,并且出现了我无法解释的这种 Postgres 行为。也许你会有什么建议?
我走得很直接(我知道这不是最有效的,但我仍然有一些时间):
create table target_table as select * from parent_table limit 0;
insert into target_table select * from parent_table where date_field >= '20120101' and date_field <='20120131' and tariff_id <> -1;
insert into target_table select * from parent_table where date_field >= '20120201' and date_field <='20120228' and tariff_id <> -1;
insert into target_table select * from parent_table where date_field >= '20120301' and date_field <='20120331' and tariff_id <> -1;
insert into target_table select * from parent_table where date_field >= '20120401' and …
Run Code Online (Sandbox Code Playgroud) 我将OpenStreetMap 的planet.osm 文件大面积导入到postgresql 数据库中。数据库包含一个称为节点的表。每个节点都有一个名为 geom 的几何列和一个名为 tags 的 hstore 列。我需要沿着标记列中具有某些键的线提取节点。为此,我使用以下查询:
SELECT id, tags
FROM nodes
WHERE ST_DWithin(nodes.geom, ST_MakeLine('{$geom1}', '{$geom2}'), 0.001)
AND tags ? '{$type}';
Run Code Online (Sandbox Code Playgroud)
$geom1 和 $geom2 是我的线的起点和终点的几何图形。
$type 变量包含我要搜索的键。现在,它可以具有以下值之一:“historic”或“tourist”。
上面给出的查询有效,但速度太慢。我想在标签列中搜索键需要太多时间。我阅读了 GIN 和 GIST 索引,并使用以下查询生成了 GIN 索引:
CREATE INDEX nodes_tags_idx ON nodes USING GIN(tags);
Run Code Online (Sandbox Code Playgroud)
创建索引后,我使用相同的第一个查询再次搜索节点,但性能没有变化。
如何正确使用 GIN 和 GIST 来索引标签列,以便我可以更快地搜索在标签列中具有特定键的节点?
谢谢
我使用以下查询来查找查询中的性能改进:
SELECT TOP 20 SUBSTRING(qt.text, (qs.statement_start_offset/2)+1,
((CASE qs.statement_end_offset
WHEN -1 THEN DATALENGTH(qt.text)
ELSE qs.statement_end_offset
END - qs.statement_start_offset)/2)+1),
qs.execution_count,
qs.total_logical_reads, qs.last_logical_reads, qs.min_logical_reads,
qs.max_logical_reads, qs.total_physical_reads, qs.last_physical_reads,
qs.min_physical_reads, qs.max_physical_reads,
qs.total_elapsed_time / 1000000 As total_elapsed_time,
qs.last_elapsed_time / 1000000 As last_elapsed_time,
qs.min_elapsed_time / 1000000 As min_elapsed_time,
qs.max_elapsed_time / 1000000 As max_elapsed_time,
qs.last_execution_time, qs.creation_time, qp.query_plan
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) qt
CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) qp
WHERE qt.encrypted=0
AND last_execution_time >= DATEADD (MINUTE , -5 , CURRENT_TIMESTAMP )
ORDER BY qs.total_logical_reads DESC
--ORDER BY qs.total_physical_reads DESC …
Run Code Online (Sandbox Code Playgroud) performance sql-server users query-performance performance-tuning
我有两张桌子levels
和users_favorites
+--------------------+--------------+------+-----+ -------+-------+ | 领域 | 类型 | 空 | 钥匙 | 默认 | 额外 | +--------------------+--------------+------+-----+ -------+-------+ | 身份证 | 整数(9) | 否 | PRI | 空 | | | 用户 ID | 整数(10) | 否 | 多| 空 | | | 级别名称 | varchar(20) | 否 | | 空 | | | 用户名 | varchar(45) | 否 | | 空 | | | 评级 | 十进制(3,2) | 否 | | 2.50 | | | 投票 …
我见过一些人建议,应O_DSYNC与SAN中使用。
MySQL 文档对 O_DSYNC 的一般情况是这样说的:
在某些版本的 GNU/Linux 和 Unix 中,使用 Unix fsync() 调用(InnoDB 默认使用)和其他类似方法将文件刷新到磁盘的速度非常慢。如果您对数据库写入性能不满意,您可以尝试将 innodb_flush_method 参数设置为 O_DSYNC。O_DSYNC 刷新方法在大多数系统上的执行速度似乎较慢,但您的可能不是其中之一。
并专门针对与SAN使用:
在某些 InnoDB 数据和日志文件位于 SAN 的系统上,对于主要包含 SELECT 语句的读取繁重的工作负载,默认值或 O_DSYNC 可能会更快。始终使用反映您的生产环境的相同类型的硬件和工作负载测试此参数。
尽管他们建议人们应该测试,但措辞是如此空洞(即“某些系统,“可能是”),如果他们甚至不费心进行测试并坚持使用默认值(fdatasync),那么人们可以原谅。但在我的(不科学的)测试我发现 O_DSYNC 提供了巨大的性能优势 - 至少对于一些麻烦的 SELECT 查询。
我想知道是否有人可以更详细地解释为什么这个选项可以在使用 SAN 时提供这样的好处。本好书当然讨论了这个选项,而不是在一个SAN的环境。
我正在使用:
我有一个包含 20 列和大约 600,000 条记录的表。最大行大小仅为 100 字节左右。该表每隔几天重新填充一次,但记录数保持大致相同。
现在只有一个聚集索引:主键的 int 标识列。
我有几个依赖于这个表的查询和视图,通常需要 5-10 秒来执行。当我简单地选择所有记录 ( select * from myTable
) 时,检索所有结果大约需要 4 秒钟。
我一直无法找到在 SQL Server 中选择 500,000 条记录的相关基准。这个时间是典型的吗?
这是我在表上执行的典型查询:
select CO.Company
,CO.Location
,CO.Account
,CO.SalesRoute
,CO.Employee
,CO.ProductType
,CO.Item
,CO.LoadJDate
,CO.CommissionRate
,SUM(CO.[Extended Sales Price]) AS Sales_Dollars
,SUM(CO.[Delivered Qty]) AS Quantity
from dbo.Commissions_Output CO
where CO.[Extended Sales Price] <> 0
group by CO.Company
,CO.Location
,CO.Account
,CO.SalesRoute
,CO.Employee
,CO.ProductType
,CO.Item
,CO.LoadJDate
,CO.CommissionRate
Run Code Online (Sandbox Code Playgroud)
当我在表上至少有一个非聚集索引时,我得到以下结果:
扫描计数 18,逻辑读取 18372;CPU 时间 = 24818 毫秒,已用时间 = 8614 毫秒。 …
performance sql-server index-tuning sql-server-2012 query-performance
我有一个存储过程,它使用 Id 列表填充临时表 #employee_benefits。该表最终大约有 10,000 行长。下面的查询然后从一个名为 EmployeeBenefitData 的表中进行选择,该表有大约 400 万行。
SELECT ebd.EmployeeBenefitDataId, ebd.EmployeeBenefitId, ebd.[DataDefinitionId]
FROM #employee_benefits eb
INNER JOIN EmployeeBenefitData ebd ON eb.EmployeeBenefitId = ebd.EmployeeBenefitId
Run Code Online (Sandbox Code Playgroud)
瓶颈是 EmployeeBenefitData 表上的索引扫描。它首先进行索引扫描,然后将其加入临时表。临时表充当过滤器,这意味着在连接之前扫描所有数据的效率非常低。我添加了以下代码以将扫描更改为搜索并显着减少所需的读取量。
DECLARE @MinEmpBenId INT, @MaxEmpBenId INT
SELECT @MinEmpBenId = MIN(EmployeeBenefitId), @MaxEmpBenId = MAX(EmployeeBenefitId)
FROM #employee_benefits
SELECT ebd.EmployeeBenefitDataId, ebd.EmployeeBenefitId, ebd.[DataDefinitionId],
dd.TypeId, dd.DataDefinitionId, dd.Name, ebd.[Value], ebd.[Date], ebd.[Text]
FROM #employee_benefits eb
INNER JOIN EmployeeBenefitData ebd ON eb.EmployeeBenefitId = ebd.EmployeeBenefitId
INNER JOIN DataDefinition dd ON ebd.DataDefinitionId = dd.DataDefinitionId
WHERE ebd.EmployeeBenefitId >= @MinEmpBenId AND ebd.EmployeeBenefitId <= @MaxEmpBenId
Run Code Online (Sandbox Code Playgroud)
它对客户端统计数据产生了巨大的影响 …
我有一个未使用现有索引的查询,我不明白为什么。
桌子:
mustang=# \d+ bss.amplifier_saturation
Table "bss.amplifier_saturation"
Column | Type | Modifiers | Storage | Description
--------+--------------------------+-------------------------------------------------------------------+---------+-------------
value | integer | not null | plain |
target | integer | not null | plain |
start | timestamp with time zone | not null | plain |
end | timestamp with time zone | not null | plain |
id | integer | not null default nextval('amplifier_saturation_id_seq'::regclass) | plain |
lddate | timestamp with time zone | not null default …
Run Code Online (Sandbox Code Playgroud) 我有一个基于主键的分区表,其中包含 15 亿行。但是当我检查.ibd
文件时,GB 中只有 80 ibd 显示,而 120ibd 显示 1MB 文件。我想知道当我使用PARTITIONS 200
. 我的结构如下。鉴于这一点id
,checksum
两者都是独一无二的。
CREATE TABLE `mapping` (
`id` varchar(50) NOT NULL DEFAULT '',
`sha_checksum` varchar(50) NOT NULL DEFAULT '',
`path_id` varchar(90) DEFAULT NULL,
`file_id` varchar(35) DEFAULT NULL,
`server_id` CHAR(6) DEFAULT NULL,
PRIMARY KEY (`id`,`sha_checksum`)
) ENGINE=InnoDB
/*!50100 PARTITION BY KEY (id,sha_checksum)
PARTITIONS 200 */
Run Code Online (Sandbox Code Playgroud)
请帮助我理解我错在哪里。
哪个更快?游标循环中的多个更新查询,还是单个查询?例如,在这种情况下,哪个更快?此查询在触发器中。
循环中的多个查询
DECLARE done INT DEFAULT FALSE;
DECLARE record_id INT;
DECLARE cur CURSOR FOR SELECT id FROM table1 WHERE column = 0;
OPEN cur;
users_loop: LOOP
FETCH cur INTO id;
IF done THEN
LEAVE users_loop;
END IF;
UPDATE table2 SET column = 0 WHERE id = id;
END LOOP;
CLOSE cur;
Run Code Online (Sandbox Code Playgroud)单一查询
CREATE TEMPORARY TABLE tmp_table (id int(10));
INSERT INTO tmp_table SELECT id FROM table1 WHERE column = 0;
UPDATE table2 SET column = 0 WHERE id IN(SELECT id FROM …
Run Code Online (Sandbox Code Playgroud)performance ×10
mysql ×4
postgresql ×3
sql-server ×3
index-tuning ×2
explain ×1
index ×1
innodb ×1
optimization ×1
order-by ×1
partitioning ×1
percona ×1
san ×1
update ×1
users ×1