簡體   English   中英

使用具有一個條件的WHERE子句或一個具有100個條件的WHERE子句的查詢運行100個SQL查詢是否更好?

[英]Is it better to run 100 SQL queries with a WHERE clause that has one condition, or one query with a WHERE clause that has 100 conditions?

使用具有一個條件的WHERE子句或一個具有100個條件的WHERE子句的查詢運行100個SQL查詢是否更好? 例如,如果我想查看表中是否已存在100個用戶名,那么迭代100個查詢或執行一次查找100個用戶名的復雜查詢會更好嗎?

我沒有做任何測試,但我更喜歡一個大的查詢。 使用100個查詢,您必須連接到數據庫,發送查詢字符串,並處理響應/結果100次。 使用一個查詢,您可以發送一個(更大的)查詢,並獲得一個響應。 我不知道100個上下文切換的確切成本,但它可能並不是無關緊要的。 無論如何,使用一個大型查詢,數據庫可能必須執行相同數量的工作。 如果您所檢查的是1個用戶名與100個用戶名,那么這不是一個非常復雜的查詢

select *
from users
where username in ('value1',...,'value100');

查詢越少越好。

少即是多。 在這種情況下,執行最少量的查詢以獲得結果。

SQL是基於設置的。 最好使用具有100個條件的子句運行一個查詢。 請記住,每個查詢代表一個單獨的隱式事務 - 因此它需要更多的開銷來運行一百個簡單查詢而不是一個復雜查詢(從處理和帶寬的角度來看)。 話雖如此,從實現的角度來看,無論性能如何,運行100個查詢都可能更容易。

恕我直言,這是個人偏好,除非你正在做一些巨大的瘋狂的東西,跨越幾張桌子等和大量的數據,速度增加不會是巨大的兩種方式。

如果您決定通過查詢完成所有操作,請確保您設置好您的密鑰和索引,否則對於每個查詢,它必須在整個表中讀取以查找它所需的內容。

如果你很好地設置你的指數,你將獲得一些巨大的速度提升。

如果你創建@table,並在@table中添加100個名稱,會更容易嗎?

按IN語句篩選查詢。

我願意打賭一個大型查詢更快......

......但不是相信我的直覺,而是有一種簡單的方法來證明它。 構建了一個簡單的性能原型並查看。

簡短的回答是它取決於。 它取決於表中的數據,您運行的where子句的類型(主鍵與多鍵等),結果集的大小等。在某些情況下,一個查詢將更快,在其他人會很多。

通常,執行的查詢越少越好。 然而,據說,100個高效查詢(例如主鍵查找)遠遠優於1個非常低效的查詢。

就您的具體問題而言,如果100個查詢相同,則將它們合並為一個。 如果它們是相關的(例如,為100個帖子提取作者),則將它們合並為一個。 如果它們彼此無關,請不要打擾它們(因為它會損害可讀性和可維護性)。

這很快但不是很漂亮:P

drop table if exists users;
create table users
(
user_id int unsigned not null auto_increment primary key,
username varbinary(32) unique not null
)
engine=innodb;

drop procedure if exists username_check;
delimiter #

create procedure username_check
(
in p_username_csv varchar(65535)
)
proc_main:begin

declare v_token varchar(255);
declare v_done tinyint unsigned default 0;
declare v_idx int unsigned default 1;

    if p_username_csv is null or length(p_username_csv) <= 0 then
        leave proc_main;
    end if;

    -- split the string into tokens and put into an in-memory table...

    create temporary table tmp(
      username varbinary(32),
      username_exists tinyint unsigned default 0,
     key (username)
    )engine = memory;   

    while not v_done do
     set v_token = trim(substring(p_username_csv, v_idx, 
      if(locate(',', p_username_csv, v_idx) > 0, 
        locate(',', p_username_csv, v_idx) - v_idx, length(p_username_csv))));

      if length(v_token) > 0 then
        set v_idx = v_idx + length(v_token) + 1;
        insert into tmp (username) values(v_token);
      else
        set v_done = 1;
      end if;
    end while;

   -- flag any that exist

    update tmp t inner join users u on t.username = u.username
      set t.username_exists = 1;

    select * from tmp order by username;

    drop temporary table if exists tmp;

end proc_main #

delimiter ;

select count(*) from users;
+----------+
| count(*) |
+----------+
|  1000000 |
+----------+
1 row in set (0.22 sec)


call username_check('user1,user2,user3... user250');

250 rows in set (0.01 sec)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM