BG Development


Страници: (3) [1] 2 3   ( Първото ново мнение ) Reply to this topicStart new topicStart Poll

> Как е най-ефективно
Gamma Goblin
Публикувано на: 23-07-2019, 20:40
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 4014
Регистриран на: 21.02.18



Quiz of the day:
----

CODE
+----+------+
| ID | Shit |
+----+------+
|  1 | s1   |
|  2 | s2   |
|  3 | s3   |
+----+------+


Как най-ефективно мога да намеря всички елементи от даден списък които *не са* в тая таблица ? Списъка е много голям, таблицата също icon_smile.gif След кратки тестове най-ефективното което измислих е с временна таблица, но малко не ме кефи icon_smile.gif

Това мнение е било редактирано от Gamma Goblin на 23-07-2019, 20:50
PMEmail PosterUsers Website
Top
Gosheto
Публикувано на: 23-07-2019, 21:05
Quote Post



Име:
Група: Потребител
Ранг: Посетител

Мнения: 84
Регистриран на: 07.05.07



Това..?

sqlfiddle
PMEmail Poster
Top
Gamma Goblin
Публикувано на: 23-07-2019, 21:13
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 4014
Регистриран на: 21.02.18



QUOTE (Gosheto @ 23-07-2019, 21:05)
Това..?

sqlfiddle

Нещо такова, но трябва да мога да си подавам нещата от списъка като променлив брой параметри, защото не знам кои и колко са предварително.

За сега най-бързо е с

CODE
explain analyze select c.guid from checker c
where not exists (select 1 from something s where s.guid = c.guid);


Като checker е временна таблица с тъпо име. Като при мен е двойно по-бързо от варианта с EXCEPT.

Това мнение е било редактирано от Gamma Goblin на 23-07-2019, 21:14
PMEmail PosterUsers Website
Top
Gamma Goblin
Публикувано на: 23-07-2019, 21:13
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 4014
Регистриран на: 21.02.18



CODE

devdb=> explain analyze select c.guid from checker c
where not exists (select 1 from something s where s.guid = c.guid);
                                                       QUERY PLAN                                                        
---------------------------------------------------------------------------------------------------------------------------
Hash Anti Join  (cost=279.00..313.74 rows=680 width=32) (actual time=6.185..6.779 rows=1000 loops=1)
  Hash Cond: ((c.guid)::text = (s.guid)::text)
  ->  Seq Scan on checker c  (cost=0.00..23.60 rows=1360 width=32) (actual time=0.021..0.392 rows=2001 loops=1)
  ->  Hash  (cost=154.00..154.00 rows=10000 width=4) (actual time=5.599..5.599 rows=10000 loops=1)
        Buckets: 16384  Batches: 1  Memory Usage: 489kB
        ->  Seq Scan on something s  (cost=0.00..154.00 rows=10000 width=4) (actual time=0.018..2.620 rows=10000 loops=1)
Planning Time: 0.211 ms
Execution Time: 6.916 ms



CODE
devdb=> explain analyze select c.guid from checker c
except select s.guid from something s;
                                                          QUERY PLAN                                                            
---------------------------------------------------------------------------------------------------------------------------------
HashSetOp Except  (cost=0.00..376.40 rows=200 width=36) (actual time=10.639..10.963 rows=1000 loops=1)
  ->  Append  (cost=0.00..348.00 rows=11360 width=36) (actual time=0.025..7.471 rows=12001 loops=1)
        ->  Subquery Scan on "*SELECT* 1"  (cost=0.00..37.20 rows=1360 width=36) (actual time=0.024..0.890 rows=2001 loops=1)
              ->  Seq Scan on checker c  (cost=0.00..23.60 rows=1360 width=32) (actual time=0.020..0.399 rows=2001 loops=1)
        ->  Subquery Scan on "*SELECT* 2"  (cost=0.00..254.00 rows=10000 width=8) (actual time=0.017..4.780 rows=10000 loops=1)
              ->  Seq Scan on something s  (cost=0.00..154.00 rows=10000 width=4) (actual time=0.016..2.641 rows=10000 loops=1)
Planning Time: 0.128 ms
Execution Time: 11.257 ms
(8 rows)
PMEmail PosterUsers Website
Top
dvader
Публикувано на: 23-07-2019, 22:50
Quote Post


Group Icon
Име: Валерий Тодоров
Група: VIP
Ранг: Почетен член

Мнения: 5404
Регистриран на: 12.07.05



Временната таблица изисква отделно куери - така нещата а) не са атомични, б) не са нишко-безопасни.

Вместо временна таблица - WITH ... SELECT
или направо някой INNER JOIN


--------------------
I find your lack of faith disturbing
PM
Top
code2
Публикувано на: 24-07-2019, 07:10
Quote Post



Име:
Група: Потребител
Ранг: Редовен член

Мнения: 557
Регистриран на: 11.06.16



Ако въпросът ти не е теоретичен, тогава защо просто не сортираш таблицата и списъка по търсения елемент и да почнеш да ги четеш паралелно с две заявки? Това би трябвало да е достатъчно ефективно.

CODE

таблица  списък
 t        l
 s1       s3
 s2       s6
 s3       s7
 s4
 s5
 s7


Алгоритъм:
CODE

while
{if(t==l) {чети ново t и l; няма някое от тях?break;  continue}
 if(t<l)  {резултат t; чети ново t; няма такова?break; continue}
 if(t>l)  {чети ново l; няма такова?break; continue}
}
имаме t?
{while
 {резултат t; чети ново t; няма такова?break;
 }
}


Това е на принципа на merge sort.

Това мнение е било редактирано от code2 на 24-07-2019, 07:11
PMEmail Poster
Top
Gamma Goblin
Публикувано на: 24-07-2019, 07:29
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 4014
Регистриран на: 21.02.18



@code2, това ще е брутално бавно
PMEmail PosterUsers Website
Top
Gamma Goblin
Публикувано на: 24-07-2019, 07:31
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 4014
Регистриран на: 21.02.18



QUOTE (dvader @ 23-07-2019, 22:50)
Временната таблица изисква отделно куери - така нещата а) не са атомични, б) не са нишко-безопасни.

Вместо временна таблица - WITH ... SELECT
или направо някой INNER JOIN

QUOTE
а) не са атомични

не е проблем

QUOTE
не са нишко-безопасни.
защо ? Временната таблица съяествува само в рамките на връзката. Като затвориш conenction-a и тя изчезва. Тоест всяка връзка си има собствена временна таблица и една връзка не може да види временната таблица на друга.
PMEmail PosterUsers Website
Top
Gamma Goblin
Публикувано на: 24-07-2019, 08:29
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 4014
Регистриран на: 21.02.18



Поради някаква прикина не ми е ползвало hash индекса icon_sad.gif Докато на fiddle-a го ползва и с временна таблица мачка: https://www.db-fiddle.com/f/wR1jaFfTZUnejmWZTMSwxY/2
PMEmail PosterUsers Website
Top
code2
Публикувано на: 24-07-2019, 08:40
Quote Post



Име:
Група: Потребител
Ранг: Редовен член

Мнения: 557
Регистриран на: 11.06.16



QUOTE (Gamma Goblin @ 24-07-2019, 07:29)
@code2, това ще е брутално бавно

Добре тогава. Ето ти по-добро решение:
CODE

create table tbl1(id INT,name VARCHAR(50),city VARCHAR(25));
create table tbl2 like tbl1;
insert into tbl1 values (1,'adam', 'eden'), (2, 'eva', 'eden');
insert into tbl2 values (3,'adam', 'eden'), (4, 'pedro', 'alexandria');

SELECT * FROM (SELECT 1 as tb_id,name,city from tbl1 UNION SELECT 2 as tb_id,name,city from tbl2) as a GROUP BY name HAVING (count(*)=1)AND(tb_id=1);

Това което направих е просто да модифицирам за нуждите вече дадено решение в stackoverflow:
https://dba.stackexchange.com/questions/102...data-repetition
Първите 4 реда в горната заявка са само за да има пълна демонстрация, както е в оригиналния цитиран отговор.
PMEmail Poster
Top
1 потребители преглеждат тази тема в момента (1 гости, 0 анонимни потребители)
Потребители, преглеждащи темата в момента:

Topic Options Страници: (3) [1] 2 3  Reply to this topicStart new topicStart Poll

 


Copyright © 2003-2019 | BG Development | All Rights Reserved
RSS 2.0