我有一个相当标准的餐厅模型,restaurant在 PostgreSQL 数据库中有一张桌子。所有餐厅都有评分(由average、vote_count和组成vote_sum),但为了避免重复此评分模式,例如pictures我将它们移到单独的rating表中并仅存储rating_idin restaurant。
我知道 1 个评级只会被整个数据库中的 1 个其他行使用。rating在restaurant或 中删除行时如何级联删除picture?
我一直在环顾四周,但我能找到的只是设置了 a REFERENCES,但为此我需要知道将删除哪些表数据。
我知道触发器可以完成这项工作,我只是希望有更优雅的东西。
除了在表上放置排他锁或重建它之外,是否有任何方法可以在删除操作期间释放堆表上的空页?这些选项都不适用于我的生产环境。
我们如何在并行的多线程环境中删除然后插入行,同时避免死锁?应用UPDLOCK和后,我仍然收到僵局SERIALIZABLE。请参阅下面的死锁错误。
资源:
我有一个 C#/ASP 应用程序在并发环境中运行两个不同的连接,尝试删除并稍后为一个人插入数据。我听说应用程序的行为有所不同。
我试过这个:
connection.BeginTransaction(System.Data.IsolationLevel.ReadCommitted))
Run Code Online (Sandbox Code Playgroud)
和
connection.BeginTransaction(System.Data.IsolationLevel.Serializable))
Run Code Online (Sandbox Code Playgroud)
上存在非聚集索引HeaderId,相同的索引Headerid可以在表中出现多次。
<event name="xml_deadlock_report" package="sqlserver" timestamp="2017-10-10T07:10:41.524Z">
<data name="xml_report">
<value>
<deadlock>
<victim-list>
<victimProcess id="process3e7eb2188" />
</victim-list>
<process-list>
<process id="process3e7eb2188" taskpriority="0" logused="26140" waitresource="KEY: 11:72057594039304192 (32fb2d1e9782)" waittime="3176" ownerId="2548574" transactionname="user_transaction" lasttranstarted="2017-10-10T00:10:38.313" XDES="0x3e7f223a8" lockMode="RangeS-U" schedulerid="8" kpid="18256" status="suspended" spid="58" sbid="0" ecid="0" priority="0" trancount="1" lastbatchstarted="2017-10-10T00:10:38.323" lastbatchcompleted="2017-10-10T00:10:38.320" lastattention="1900-01-01T00:00:00.320" clientapp=".Net SqlClient Data Provider" hostname="JOHN-SMITH" hostpid="12976" loginname="johnsmith" isolationlevel="serializable (4)" xactid="2548574" currentdb="11" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
<executionStack>
<frame …Run Code Online (Sandbox Code Playgroud) 我正在运行连接到 SQL Server 2012 数据库的 Web 服务。在短时间内(大约 5 秒)内执行多个删除查询时,实际执行的查询似乎是随机的。当一次运行一个或在每次执行之间放置 0.5 秒的延迟时,它们运行完美。
查看 SQL 分析器,所有查询都显示为RPC:Completed即使它们实际上并未删除表中的行。我检查了表,数据仍然存在,然后将查询从 Profiler 复制并粘贴到 SSMS 中,这影响了一行并将其删除。
所以我假设 Web 服务运行良好,问题出在它的数据库端。探查器中有没有办法查看查询是否成功?什么可能导致这实际上不影响行?
没有触发器。仅使用不同的参数运行相同的查询。只有数据通常是按顺序变化的。刚才没有其他查询在数据库上运行。
我添加了客户端站点日志记录,如果它删除该行,它实际上会返回 1,如果它不删除该行,它会返回 0。然而,即使它出现为 0,Profiler 也会显示它已经运行了查询,但似乎没有影响它。当我通过 SSMS 运行查询时,它确实会影响该行。
未收到来自 Web 服务的任何错误,并且查询通过 SSMS 运行良好。只有在快速连续多次运行时似乎不会删除。我确实同意它很可能针对不同的行,但是当它在 SSMS 中运行正常时看不到它是如何发生的。
CREATE TABLE dbo.ContractDates2HumanAssets
(
iContractDate2HumanAssetID int IDENTITY(1,1) NOT NULL,
iContractDateID int NOT NULL,
iHumanAssetID int NOT NULL,
cCategory nvarchar(256) NOT NULL,
cHR_x0020_ID nvarchar(256) NOT NULL,
cCD_x0020_ID nvarchar(256) NOT NULL,
CONSTRAINT PK_ContractDates2HumanAssets PRIMARY KEY CLUSTERED
(
iContractDate2HumanAssetID ASC
) WITH (PAD_INDEX = …Run Code Online (Sandbox Code Playgroud) 我得到了一个合理的简单查询:
With RowsToDelete AS
(
SELECT TOP 500 Id
FROM ErrorReports
WHERE IncidentId = 611
)
DELETE FROM RowsToDelete
Run Code Online (Sandbox Code Playgroud)
但是,它没有完成。我已经尝试了几次。上次我等了 8 分钟才取消。
ErrorReports包含大约 22 000 行。ErrorReportOrigins差不多。
预计执行计划:
实际执行计划(对于top 10,需要 28 秒才能完成):
执行计划:https : //www.brentozar.com/pastetheplan/?id=S1jUXDruz
客户统计:
我试过的:
ErrorReportOrigins没有聚集索引 (id),只有一个 FK 到ErrorReports.Id. 我添加了一个 id 列(pk&identity)。ErrorReportOrigins第一个删除(使用相同的 CTE)。没有不同ORDER BY Id,我把它去掉看看有没有区别)我迷路了。为什么要花这么长时间?所有 SELECT 语句都很快。而且数据库并不是很大。该ErrorReports表是最大的一个。
(这是一个弹性池中的 SQL Azure DB)
更新
CREATE TABLE [dbo].[ErrorReports](
[Id] [int] IDENTITY(1,1) …Run Code Online (Sandbox Code Playgroud) 我需要删除此表中的重复记录。但是,id每一行都没有。
| 产品 | 数量 | 数量 |
|---|---|---|
| 桌子 | 2000年 | 5 |
| 椅子 | 300 | 25 |
| 电视 | 30000 | 4 |
| 自行车 | 300 | 25 |
| 桌子 | 2000年 | 5 |
| 椅子 | 300 | 25 |
| 椅子 | 300 | 25 |
我需要得到这个结果。
| 产品 | 数量 | 数量 |
|---|---|---|
| 桌子 | 2000年 | 5 |
| 椅子 | 300 | 25 |
| 电视 | 30000 | 4 |
| 自行车 | 300 | 25 |
如果有id,我可以使用:
DELETE p1 FROM products p1
INNER JOIN products p2
WHERE p1.id < p2.id AND p1.product = p2.product;
Run Code Online (Sandbox Code Playgroud) 现在,我知道日志在大删除过程中会变大,应该尝试将其分成几批。但我觉得这种情况很奇怪,如果有人能向我解释,那就太好了!
我有一个 27GB 的数据库和大约 30GB 的日志。被删除的表大小约为 15GB,其中有 2000 万条记录。该表有 20 列,只有 bigint 和 int 数据类型。
删除操作是从相关表中删除 1800 万条重复记录。我已切换选择进行删除以确保记录计数匹配并且确实如此。
在我用完磁盘空间并被迫回滚之前,日志增长到大约 110GB。
表上没有触发器,只有16个非聚集索引,没有聚集索引。如果我在运行操作之前禁用所有索引,它会完成而不会从原始大小增加日志。
所以我的问题是,从表中删除时,我是否记录了每个索引的每次删除?如果是这样,这是正常行为还是可能是因为缺少聚集索引?
下面是一个有效的 TSQL 语句。但我想了解 SQL Server 如何处理它。
DELETE A
FROM table1 WITH (NOLOCK)
WHERE
EXISTS
(
SELECT 1
FROM
table2 B WITH (NOLOCK)
WHERE
B.id = A.id
)
Run Code Online (Sandbox Code Playgroud)
因为子查询的输出将是一个 1 的列表。SQL Server 如何知道要删除哪些行?
我有一个包含大约 10 亿个条目的 innodb 表。我开始了一个删除操作(在索引列上有一个小的 where 条件),它应该删除很多条目,留下大约 1 亿条。删除操作现在运行了 2 天,几个小时前我收到一个错误“在查询过程中丢失了与 mysql 服务器的连接”。mysql processlist 命令显示状态为“正在更新”的删除操作,因此尽管命令行向我显示了此错误,但查询似乎仍在运行。我怎样才能追查到这一点?我基本上不知道它是否仍在删除或卡住。我害怕杀死进程,因为我不想触发回滚。
我有tableA4 列:
IDA(bigint)、IDB(int)、IDC(varchar(255)) 和comment(varchar(255))。主键是 ( IDA, IDB, IDC)。
我需要删除 ( IDA, IDB)计数大于 1 且comment为“temp”的记录。我想出了以下 SQL 语句:
DELETE FROM tableA WHERE IDA, IDB IN
(SELECT IDA, IDB FROM tableA GROUP BY IDA, IDB HAVING COUNT(*) > 1)
AND comment = 'temp'
但我收到以下错误:“在预期条件的上下文中指定的非布尔类型的表达式,靠近 ','。[...]”
使用 Microsoft SQL Server Enterprise Edition v9.00.3042.00,即 SQL Server 2005 Service Pack 2
我很新,很感激任何帮助/建议。
delete ×10
sql-server ×7
mysql ×2
cascade ×1
concurrency ×1
constraint ×1
duplication ×1
exists ×1
heap ×1
innodb ×1
insert ×1
mysql-5.7 ×1
postgresql ×1
profiler ×1
t-sql ×1