小编Qua*_*noi的帖子

如何有效地删除Postgresql 8.1表中的行?

我正在研究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)

sql database postgresql

6
推荐指数
2
解决办法
2万
查看次数

如何在表格中获得第一个未使用的ID?

我必须编写一个查询,其中我需要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 ..

mysql sql

6
推荐指数
2
解决办法
8596
查看次数

TSQL SELECT然后在一个事务中UPDATE,然后返回SELECT

我在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大师,所以一些帮助将不胜感激.

sql t-sql coldfusion select stored-procedures

6
推荐指数
1
解决办法
7702
查看次数

带有独占锁定的MySQL InnoDB死锁(FOR UPDATE)

我这样做是为了确保只运行一次这个进程的实例(伪代码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)

mysql deadlock innodb transactions

6
推荐指数
2
解决办法
6904
查看次数

两个SUM查询在一起

我有一个表"事件"和一个表"插槽",其中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)

sql t-sql sql-server

5
推荐指数
1
解决办法
274
查看次数

将数据时间字段与MySQL中的当前日期时间进行比较

我有类似的东西:

to_days(now()) < to_days(birth)
Run Code Online (Sandbox Code Playgroud)

它可以工作,但我不是比较时间来比较时间.有类似的功能吗?

mysql sql

5
推荐指数
1
解决办法
5296
查看次数

需要更新mysql查询,以选择预订酒店房间或任何东西的日期范围

我的项目情况如下.

在检查可用房间时

$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

需要任何澄清请问我.

谢谢.

php mysql sql

5
推荐指数
1
解决办法
1672
查看次数

MYSQL,WHERE / LIMIT / ORDERBY的组合

我有这个

$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)

我究竟做错了什么?

mysql limit where

5
推荐指数
1
解决办法
2万
查看次数

GROUP_CONCAT更改GROUP BY顺序

我有一个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)

mysql group-concat

5
推荐指数
3
解决办法
3133
查看次数

加入oracle表值函数

是否可以加入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)

oracle inner-join user-defined-functions

5
推荐指数
1
解决办法
9999
查看次数