我正在使用亚马逊的RDS数据库和一些非常大的表,昨天我开始面临服务器上100%的CPU利用率和一堆以前没有发生的慢速查询日志.
我试图检查正在运行的查询并从explain命令面对此结果
+----+-------------+-------------------------------+--------+----------------------------------------------------------------------------------------------+---------------------------------------+---------+-----------------------------------------------------------------+------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------------------------+--------+----------------------------------------------------------------------------------------------+---------------------------------------+---------+-----------------------------------------------------------------+------+----------------------------------------------+
| 1 | SIMPLE | businesses | const | PRIMARY | PRIMARY | 4 | const | 1 | Using index; Using temporary; Using filesort |
| 1 | SIMPLE | activities_businesses | ref | PRIMARY,index_activities_users_on_business_id,index_tweets_users_on_tweet_id_and_business_id | index_activities_users_on_business_id | 9 | const | 2252 | Using index condition; Using where |
| 1 | SIMPLE …Run Code Online (Sandbox Code Playgroud) mysql database-performance query-performance amazon-rds mysql-slow-query-log
为了论证,让我们说它适用于SQL 2005/8.我知道当您在表上放置索引来调整SELECT语句时,这些索引需要在INSERT/ UPDATE/ DELETEactions 期间进行维护.
我的主要问题是:
SQL Server何时维护表的索引?
我有很多后续问题:
我天真地假设它会在命令执行后执行.假设您要插入20行,它将在插入和提交20行后维护索引.
在脚本具有针对表的多个语句但其他方式是不同的语句的情况下会发生什么?
服务器是否具有在执行所有语句后维护索引的智能,还是在每个语句中执行此操作?
我已经看到了在大/多INSERT/ UPDATE动作之后删除索引并重新创建的情况.
即使您只更改了少量行,这可能会导致重建整个表的索引?
尝试整理INSERT和
UPDATE操作到更大的批处理中是否会有性能优势,例如通过收集要插入临时表的行,而不是执行许多较小的插入?
抱歉问题激增 - 这是我一直都知道的事情,但在尝试调整脚本以获得平衡时,我发现我实际上并不知道索引维护何时发生.
编辑:我知道性能问题在很大程度上取决于插入/更新期间的数据量和索引数量.再次为了论证,我有两种情况:
这两种情况都有一个大的插入/更新批次,比如10k +行.
编辑2:我知道能够在数据集上分析给定的脚本.但是,分析并不能告诉我为什么给定的方法比另一种更快.我对索引背后的理论以及性能问题所依据的理论更感兴趣,而不是一个明确的"这比那个更快"的答案.
谢谢.
问题
我试图理解为什么在这两个Oracle语法更新查询中看起来微不足道的原因导致执行计划完全不同.
查询1:
UPDATE sales s
SET status = 'DONE', trandate = sysdate
WHERE EXISTS (Select *
FROM tempTable tmp
WHERE s.key1 = tmp.key1
AND s.key2 = tmp.key2
AND s.key3 = tmp.key3)
Run Code Online (Sandbox Code Playgroud)
查询2:
UPDATE sales s
SET status = 'DONE', trandate = sysdate
WHERE EXISTS (Select rownum
FROM tempTable tmp
WHERE s.key1 = tmp.key1
AND s.key2 = tmp.key2
AND s.key3 = tmp.key3)
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,两者之间的唯一区别是查询2中的子查询返回rownum而不是每行的值.
这两者的执行计划不可能更加不同:
Query1 - 从两个表中提取总结果,并使用sort和hashjoin返回结果.这有利于2,346的成本(尽管使用了EXISTS条款和有凝聚力的子查询).
Query2 - 同时拉取两个表结果,但使用计数和过滤器来完成相同的任务,并以惊人的77,789,696成本返回执行计划!我应该注意到他的查询只是挂在我身上所以我实际上并不是肯定的,这会返回相同的结果(尽管我相信它应该).
根据我对Exists子句的理解,它只是一个简单的布尔检查,它运行在主表的每一行.如果在我的EXISTS条件中返回单行或100,000行也没关系...如果为正在运行的行返回任何结果,那么您已经通过了存在检查.那么为什么我的子查询SELECT语句返回的重要性呢?
- - - - - - - - - …
我有一个针对你的SQL性能大师的高级SQL问题:-)
我目前正在尝试理解更大的应用程序中的一些行为,但它归结为针对这两个表的查询:
Userstable - 大约750个条目,UserId(varchar(50))as clustered PKActionLog表 - 数百万条目,包括UserId- 但没有FK关系对于我的ASP.NET应用程序中的网格,我试图让所有用户加上他们上次日志条目的日期.
当前使用的SQL语句如下所示:
SELECT
UserId, (other columns),
LastLogDate = (SELECT TOP (1) [Timestamp] FROM dbo.ActionLog a WHERE a.UserId = u.UserId ORDER BY [Timestamp] DESC)
FROM
dbo.Users u;
Run Code Online (Sandbox Code Playgroud)
并返回要显示的行 - 但它相当慢(大约20秒).
我的第一个想法是在ActionLog表上添加一个索引UserId并在其中包含Timestamp列:
CREATE NONCLUSTERED INDEX [IDX_UserId]
ON [dbo].[ActionLog]([UserId] ASC)
INCLUDE ([Timestamp])
Run Code Online (Sandbox Code Playgroud)
这些行现在非常快速地返回 - 在2秒内,表中有350'000个条目ActionLog,我的索引正在使用,正如执行计划显示的那样.一切似乎都很好.
现在,为了近似生产场景,我们在ActionLog表中加载了大约200万行,其中95%或更多是指不存在的用户(即这些行具有表UserId中不存在的行Users).
现在突然,查询变得非常慢(24分钟!),并且索引不再被使用.
我认为,由于表中的绝大多数条目 …
请记住这两种类型的查询:
--query1
Select someFields
From someTables
Where someWhereClues
Union all
Select someFields
FROM some Tables
Where someWhereClues
--query2
Select * FROM (
Select someFields
From someTables
Union all
Select someFields
FROM someTables
) DT
Where someMixedWhereClues
Run Code Online (Sandbox Code Playgroud)
注意:
在两个查询中,最终结果字段都相同
我想到了第一个.查询更快或性能更好!
但经过一些研究后我对此笔记感到困惑:
SQL Server(作为RDBMS的示例)首先读取整个数据然后查找记录.=>所以在两个查询中所有记录都将读取和搜索.
请帮助我解决我的误解,以及query1和query2之间是否有任何其他差异?
编辑:添加样本计划:
select t.Name, t.type from sys.tables t where t.type = 'U'
union all
select t.Name, t.type from sys.objects t where t.type = 'U'
select * from (
select t.Name, t.type from sys.tables t
union …Run Code Online (Sandbox Code Playgroud) 我写了一个查询来更新整个表.如何改进此查询以减少时间:
update page_densities set density = round(density - 0.001, 2)
Run Code Online (Sandbox Code Playgroud)
查询成功返回:受影响的行为628391行,执行时间为1754179毫秒(29分钟).
编辑:通过设置工作记忆..
set work_mem = '500MB';
update page_densities set density = round(density - 0.001, 2)
Run Code Online (Sandbox Code Playgroud)
查询成功返回:628391行受影响,731711毫秒(12分钟)执行时间.
多年来,我一直在阅读/听到关于bigint列上的数据库连接的"性能优势" OVER加入(var)char列.
不幸的是,在寻找关于'simlilar type questions'的真实答案/建议时:
我没有看到使用Hive版本(最好是版本1.2.1或更高版本)的示例,其中大型(BIG-DATA-ISH)数据集(假设5亿个+行)连接到类似大小的数据集:
我选择32的大小,因为它是MD5哈希的大小,转换为字符和255,因为它是我所见过的最大自然键的"范围".
此外,我希望Hive:
有没有人知道这样的例子,通过展示Hive Explain计划,CPU,文件和网络资源+查询运行时证明了证据?
我有一个性能不佳的查询...我做错了什么?请帮助我,它在我的系统中执行了无数次,解决后将带给我通往天堂的阶梯
我使用sp_Blitz对系统进行了检查,未发现任何致命问题
这是查询:
SELECT MAX(F.id) OVER (PARTITION BY idstato ORDER BY F.id DESC) AS id
FROM jfel_tagxml_invoicedigi F
INNER JOIN jfel_invoice_state S ON F.id = S.idinvoice
WHERE S.idstato = @idstato
AND S.id = F.idstatocorrente
AND F.sequence_invoice % @number_service_installed = @idServizio
ORDER BY F.id DESC,
F.idstatocorrente OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY;
Run Code Online (Sandbox Code Playgroud)
这是查询计划
https://www.brentozar.com/pastetheplan/?id=SyYL5JOeE
我可以私下向您发送我的系统属性
更新:进行了一些修改,它是更好,但我认为可能会更好...这是新的查询:
SELECT MAX(F.id) AS id
FROM jfel_tagxml_invoicedigi F
INNER JOIN jfel_invoice_state S ON F.id = S.idinvoice
WHERE S.idstato = @idstato
AND S.id = F.idstatocorrente …Run Code Online (Sandbox Code Playgroud) 所以我有一个小而简单的Redis数据库。它包含 136689 个键,其值是包含 27 个字段的哈希映射。我正在通过服务器节点上的 Python 接口访问该表,并且每次调用需要加载大约 1000-1500 个值(最终我将看到每秒大约 10 个请求)。一个简单的调用看起来像这样:
# below keys is a list of approximately 1000 integers,
# not all of which are in the table
import redis
db = redis.StrictRedis(
host='127.0.0.1',
port=6379,
db=0,
socket_timeout=1,
socket_connection_timeout=1,
decode_responses=True
)
with db.pipeline() as pipe:
for key in keys:
pipe.hgetall(key)
results = zip(keys,pipe.execute())
Run Code Online (Sandbox Code Playgroud)
总时间约为 328 毫秒,每个请求的平均时间约为 0.25 毫秒。
问题:这对于小型数据库来说非常慢,每秒查询次数相对较少。我的配置或我调用服务器的方式有问题吗?可以做些什么来加快速度吗?我不希望桌子变得更大,所以我很高兴为了速度而牺牲磁盘空间。
调用hget每个键(没有管道)较慢(如预期)并显示时间分布是双峰的。较小的峰值对应于不在表中的键,而较大的峰值对应于表中的键。
我的conf文件如下:
port 6379
daemonize yes
save ""
bind 127.0.0.1
tcp-keepalive 300
dbfilename mytable.rdb
dir . …Run Code Online (Sandbox Code Playgroud) python performance database-performance query-performance redis
我有一张包含超过 2.6 亿条记录的表。我已经为表创建了分区并对其进行了索引。
CREATE TABLE qt_al_90k
(
rec_id integer,
user_id integer,
user_text text,
user_number double precision,
user_date date,
user_seq integer,
my_sequence integer
) PARTITION BY RANGE (rec_id);
Run Code Online (Sandbox Code Playgroud)
分区查询:
CREATE TABLE qt_al_90k_rec_id_1 PARTITION OF qt_al_90k FOR VALUES FROM (0) TO (100000);
CREATE TABLE qt_al_90k_rec_id_2 PARTITION OF qt_al_90k FOR VALUES FROM (100000) TO (200000);
CREATE TABLE qt_al_90k_rec_id_3 PARTITION OF qt_al_90k FOR VALUES FROM (200000) TO (300000);
CREATE TABLE qt_al_90k_rec_id_4 PARTITION OF qt_al_90k FOR VALUES FROM (300000) TO (400000);
CREATE TABLE qt_al_90k_rec_id_5 PARTITION …Run Code Online (Sandbox Code Playgroud) performance ×4
sql-server ×4
sql ×3
postgresql ×2
amazon-rds ×1
exists ×1
hive ×1
indexing ×1
int ×1
join ×1
max ×1
mysql ×1
oracle ×1
python ×1
rdbms ×1
redis ×1
rownum ×1
union ×1
varchar ×1