我正在研究PostgreSQL 8.1 SQL脚本,它需要从表中删除大量行.
假设我需要删除的表是Employees(~260K行).它的主键名为id.
我需要从此表中删除的行存储在一个名为EmployeesToDelete(~10K记录)的单独临时表中,其中包含一个名为employee_id的Employees.id的外键引用.
有没有一种有效的方法来做到这一点?
起初,我想到了以下几点:
DELETE
FROM Employees
WHERE id IN
(
SELECT employee_id
FROM EmployeesToDelete
)
Run Code Online (Sandbox Code Playgroud)
但我听说使用"IN"子句和子查询可能效率低下,尤其是对于较大的表.
我查看了PostgreSQL 8.1文档,并提到了DELETE FROM ... USING但它没有示例,所以我不知道如何使用它.
我想知道以下是否有效并且效率更高?
DELETE
FROM Employees
USING Employees e
INNER JOIN
EmployeesToDelete ed
ON e.id = ed.employee_id
Run Code Online (Sandbox Code Playgroud)
非常感谢您的意见.
编辑:我运行了EXPLAIN ANALYZE,奇怪的是第一个DELETE跑得很快(几秒钟内),而第二个DELETE花了这么长时间(超过20分钟)我最终取消了它.
向临时表添加索引有助于提高性能.
这是对任何感兴趣的人的第一个DELETE的查询计划:
Hash Join (cost=184.64..7854.69 rows=256482 width=6) (actual time=54.089..660.788 rows=27295 loops=1)
Hash Cond: ("outer".id = "inner".employee_id)
-> Seq Scan on Employees (cost=0.00..3822.82 rows=256482 width=10) (actual time=15.218..351.978 rows=256482 loops=1)
-> Hash (cost=184.14..184.14 rows=200 width=4) (actual time=38.807..38.807 rows=10731 loops=1) …
Run Code Online (Sandbox Code Playgroud) 我必须编写一个查询,其中我需要ID
为特定记录分配一个(唯一密钥),该记录未被使用/未被生成/在数据库中不存在.
简而言之,我需要id
为特定记录生成一个并在打印屏幕上显示它.
E. g.:
ID Name 1 abc 2 def 5 ghi
所以,问题是它应该ID=3
作为尚未生成的下一个立即返回,并且在这一代之后id
,我将把这些数据存储回数据库表.
它不是一个硬件:我正在做一个项目,我有一个要求,我需要编写这个查询,所以我需要一些帮助来实现这一目标.
所以请指导我如何进行此查询,或如何实现此目的.
谢谢.
我无法添加评论,这就是为什么我在这里写我的评论..我使用MySQL作为数据库..
我的步骤是这样的: -
1)从数据库表中检索未使用的id.
2)因为他们不是.用户(基于网站的项目),所以我不想发生并发,所以如果一个用户生成一个ID,那么它应该锁定数据库,直到同一个用户收到id并存储该id的记录.之后,其他用户可以检索不存在的ID.(主要要求)..
我怎么能在MySQL中实现所有这些东西,而且我认为Quassnoi的答案是值得的,但它不适用于MySQL ..所以plz解释有关查询的一点,因为它对我来说是新的..并且这个查询工作在MySQL ..
我在ColdFusion应用程序中遇到查询时遇到问题(回溯到MS SQL 2008).我一直在这个事务上遇到数据库死锁错误:
<code>
<cftransaction>
<cfquery name="selectQuery">
SELECT TOP 20 item_id, field2, field3
FROM Table1
WHERE subject_id = #subject_ID# AND lock_field IS NULL AND
NOT EXISTS (SELECT * FROM Table2 WHERE Table2.user_ID = #user_ID# Table1.item_id = Table2.item_id)
</cfquery>
<cfquery name="updateQuery">
UPDATE Table1
SET lock_field = 1, locked_by = #user_ID#
WHERE Table1.item_id IN (#ValueList(selectQuery.item_id#)
</cfquery>
</cftransaction>
</code>
Run Code Online (Sandbox Code Playgroud)
基本上,我有一个表(Table1),表示一大堆等待项.用户"结账"项目给他们一个分数.一次只有一个用户可以检出项目.我需要为给定用户一次请求一个包含20个项目的块.这些项目尚未签出,用户之前也无法对其进行评分(因此SELECT中的lock_field为IS NULL和NOT EXISTS语句).一旦我确定了20个item_id的列表,我就需要更新队列表以将它们标记为已锁定,这样就不会有其他人同时检查它们.我还需要返回item_ids列表.
我认为如果我将它从cftransaction移动到SQL Server端的存储过程,它可能会更好.我只是不确定cftransaction锁定是否以某种方式干扰.我不是TSQL大师,所以一些帮助将不胜感激.
我这样做是为了确保只运行一次这个进程的实例(伪代码php/mysql innodb):
START TRANSACTION
$rpid = SELECT `value` FROM locks WHERE name = "lock_name" FOR UPDATE
$pid = posix_getpid();
if($rpid > 0){
$isRunning = posix_kill($rpid, 0);
if(!$isRunning){ // isRunning
INSERT INTO locks values('lock_name', $pid) ON DUPLICATE KEY UPDATE `value` = VALUES(`value`)
}else{
ROLLBACK
echo "Allready running...\n";
exit();
}
}else{ // if rpid == 0 -
INSERT INTO locks values('lock_name', $pid) ON DUPLICATE KEY UPDATE `value` = VALUES(`value`)
}
COMMIT
...............
//free the pid
INSERT INTO locks values('lock_name', 0) ON DUPLICATE …
Run Code Online (Sandbox Code Playgroud) 我有一个表"事件"和一个表"插槽",其中Slots.SlotID = Events.MainSlot OR Events.ExtraSlot.
我需要将每个时间段的"参加者"数量相加(因为MainSlot和ExtraSlot - ExtraSlot是可选的)
表"事件"
ID------Name----------MainSlot-------ExtraSlot-------Attendees
1-------Event1--------1 -------------n/a-------------20
2-------Event2--------1 -------------n/a-------------20
3-------Event3--------2 -------------n/a-------------40
4-------Event4--------2 -------------3---------------20
5-------Event5--------3 -------------4---------------40
6-------Event6--------3 -------------4---------------20
7-------Event7--------3 -------------4---------------10
Run Code Online (Sandbox Code Playgroud)
表"老虎机"
SlotID--- Slot
1-------- 9.00-9.30
2-------- 9.30-10
3-------- 10.30-10.30
4-------- 10.30-11
Run Code Online (Sandbox Code Playgroud)
如果我单独查询数据库,如下所示:
SELECT s.Slot, s.SlotID, ISNULL(SUM(e. Attendees), 0) AS Attendees1
FROM Slots AS s
LEFT OUTER JOIN Events AS e ON e.MainSlot = s.SlotID
GROUP BY s.Slot, s.SlotID
Run Code Online (Sandbox Code Playgroud)
...要么:
SELECT s.Slot, s.SlotID, ISNULL(SUM(x.Attendees), 0) AS Attendees2
FROM Slots AS s
LEFT OUTER JOIN Events AS x …
Run Code Online (Sandbox Code Playgroud) 我有类似的东西:
to_days(now()) < to_days(birth)
Run Code Online (Sandbox Code Playgroud)
它可以工作,但我不是比较时间来比较时间.有类似的功能吗?
我的项目情况如下.
在检查可用房间时
$sel_from_bookings="SELECT room_no FROM `booking` WHERE (('".$_POST['req_tdate']."' BETWEEN check_indate AND check_outdate) OR ('".$_POST['req_fdate']."' BETWEEN check_indate AND check_outdate)";
$sel_from_reserv="SELECT room_no FROM `reservation` WHERE (('".$_POST['req_tdate']."' BETWEEN check_indate AND check_outdate) OR ('".$_POST['req_fdate']."' BETWEEN check_indate AND check_outdate))";
$sel_rooms="SELECT room_no FROM rooms WHERE room_no NOT IN (".$sel_from_bookings.") AND room_no NOT IN (".$sel_from_reserv.")";
Run Code Online (Sandbox Code Playgroud)
第一个查询从预订表中检索满足日期范围的房间号列表
类似地,第二个与表预约相同
最后一个查询使用上述两个查询提供的列表,并获取不在生成列表中的房间列表.
适用于10-08-2010/15-08-2010
适用于20-08-2010/25-08-2010
当我给出10到15之间的日期时,它同样适用于20和25,并且在14-08-2010和21-08-2010的日期也可以正常工作
但不适用于16-08-2010至19-08-2010
需要任何澄清请问我.
谢谢.
我有这个
$sql = 'SELECT * FROM tb_event WHERE DATE(edate) >= DATE(NOW())';
$result = $conn->query($sql) or die(mysqli_error());
$news = $result->fetch_assoc();
Run Code Online (Sandbox Code Playgroud)
运行正常但是当我将其更改为此
$sql = 'SELECT * FROM tb_event WHERE DATE(edate) >= DATE(NOW() LIMIT 2)';
Run Code Online (Sandbox Code Playgroud)
我收到此错误消息
Warning: mysqli_error() expects exactly 1 parameter, 0 given in /var/www/.../...php
Run Code Online (Sandbox Code Playgroud)
最后,我想将其与订单结合起来,就像这样
$sql = 'SELECT * FROM tb_event WHERE DATE(edate) >= DATE(NOW() LIMIT 2 ORDER BY DESC)';
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
我有一个VIEW(很多连接)输出按日期ASC排序的数据.按预期工作.
输出类似于:
ID date tag1 other_data
1 25-03-2011 blue fff <=
1 26-03-2011 red ggg
1 27-03-2011 pink yyy
2 25-03-2011 red yyy <=
2 26-03-2011 orange rrr
Run Code Online (Sandbox Code Playgroud)
如果我申请GROUP BY ID
.对于其他列,MySQL输出每个ID的第一个找到的行.我在te docs的某个地方读到了这个.
SELECT * FROM `myVIEW`
GROUP BY `ID`
ID date tag1 other_data
1 25-03-2011 blue fff <=
2 25-03-2011 red yyy <=
Run Code Online (Sandbox Code Playgroud)
现在让我们添加一个GROUP_CONCAT(tags1
)
SELECT *,CONCAT_GROUP(`tag1`) AS `tags`
FROM `myVIEW`
GROUP BY `ID`
Run Code Online (Sandbox Code Playgroud)
由于我应用CONCAT_GROUP,结果变得奇怪.我在期待:
ID date tag1 other_data tags
1 25-03-2011 blue fff blue,red,pink
2 …
Run Code Online (Sandbox Code Playgroud) 是否可以加入Oracle表值函数?
SELECT
*
FROM
SOME_TABLE a
INNER JOIN
TABLE(GET_TABLE_LIST()) b ON = a.COL_A = b.COL_A
Run Code Online (Sandbox Code Playgroud) mysql ×6
sql ×6
t-sql ×2
coldfusion ×1
database ×1
deadlock ×1
group-concat ×1
inner-join ×1
innodb ×1
limit ×1
oracle ×1
php ×1
postgresql ×1
select ×1
sql-server ×1
transactions ×1
where ×1