Тема: Найшвидший спосіб замінити рядки

Задача: потрібно дістати з БД таблицю і в одному з рядків замінити "комп'ютері" найменування на "людські", перед кожним виводом таблиці на веб-сторінку. (Нічого не зберігається, просто вибірка)

Наприклад:
В таблиці є назви "NAME_WORK", "TIME_1", "NEW_PAGE" їх потрібно замінити на "Ім'я роботи", "Час (перший)", "Ім'я сторінки"

Проблема:
На сервері знаходиться "захардкоджений" словник з "комп'ютерними" та "людськими" назвами:

public Dictionary<string, string> fieldnames = new Dictionary<string, string> {
            {"NAME_WORK", "Ім'я роботи"},
            {"TIME_1", "Час (перший)"},
...

В БД є також таблиця з назвами:

NAME | TOSHOWNAME
***********************
NEW_PAGE | Ім'я сторінки
NEW_ITEM | Новий елемент
...
***********************

Тобто є два джерела звідки можна отримати ім'я:
1 - пошукати в словнику, якщо немає в словнику 2 - пошукати в БД.

Словник і таблиця з іменами має велику кількість рядків.

Сама таблицю, яку потрібно показати велика, може бути до 100'000+ рядків.

Питання: який можна придумати оптимальний спосіб замінити імена в такій ситуації ?

2

Re: Найшвидший спосіб замінити рядки

1. Проіндексувати таблицю назв
2.

SELECT ..., COALESCE(NAMES.TOSHOWNAME, TABLE.NAME), ... 
FROM TABLE LEFT JOIN NAMES ON TABLE.NAME = NAMES.NAME ...

3. Результати прогнати через словник.

Подякували: Betterthanyou1

3

Re: Найшвидший спосіб замінити рядки

with data as (
    select 'комп''ютерний1' as t1 union all 
    select 'комп''ютерний2' as t1 union all 
    select 'комп''ютерний3' as t1 union all 
    select 'нейтральний'
)
select 
case when t1 = 'комп''ютерний1' 
     then 'людський1' 
     else 
        case when t1 = 'комп''ютерний2' 
            then 'людський2' 
            else 
                case when t1 = 'комп''ютерний3' 
                    then 'людський3' 
                else t1 
                end
        end
end as t1 from data;

t1
людський1
людський2
людський3
нейтральний

4

Re: Найшвидший спосіб замінити рядки

Betterthanyou написав:

Словник і таблиця з іменами має велику кількість рядків.

frz, довгенько будете писати запит... а потім він довгенько працюватиме.

5

Re: Найшвидший спосіб замінити рядки

Тоді так:

create table translate_comp_to_human (
    id serial,
    original varchar(200),
    translated varchar(200)
);

insert into translate_comp_to_human (
    original, translated
)
select 'комп''ютерний1' as original, 'людський1' as translated union all 
select 'комп''ютерний2' as original, 'людський2' as translated union all 
select 'комп''ютерний3' as original, 'людський3' as translated;

with data as (
    select 'комп''ютерний1' as t1 union all 
    select 'комп''ютерний2' as t1 union all 
    select 'комп''ютерний3' as t1 union all 
    select 'нейтральний'
)
select coalesce(t.translated,d.t1) as t1 
from data as d left join translate_comp_to_human as t on d.t1 = t.original;

t1
людський1
людський2
людський3
нейтральний

На жаль, varchar недоцільно індексувати. Тому якщо там сотні мільйонів записів, то перформанс джойну по варчару буде такий собі.
Тестовано на постґрес.

6

Re: Найшвидший спосіб замінити рядки

frz написав:

varchar недоцільно індексувати

Чому? Ні, звісно, можна вручну вираховувати хеш з VARCHAR, додати ще один стовпчик і робити JOIN по ньому, якщо там багато повторів, то може мати сенс, але ніби VARCHAR притомної довжини непогано індексується.

7

Re: Найшвидший спосіб замінити рядки

Це в мене на рівні відчуттів. Індекс на varchar протирічить загальнолюдській моралі ))
Під прицілом кулемета може й зробив би. Хеш значно краще.
Недарма стільки нюансів, легко наґуґлити "varchar index performance".

Хоча автор не вказав тип БД. Може для конкретної бази кількість можливих іш'ю менша.

Прихований текст

А в Snowflake взагалі не існує поняття індексів.