Как стать автором
Обновить
4
0

Пользователь

Отправить сообщение

Выглядит как заметка об иммутабельности строк. В c#, например, интернирование строк тема достаточно интересная, но большая часть темы уже касается не простого запихивания одних и тех же констант в массив, а о поведении при операциях со строками, вроде склеивания (var word ="word" и var word2 = "wo" + "rd" - это и то же?).

На ноутбучных платах же бывает, что оперативная память распаяна в некотором небольшом объёме и представляет собой неизвлекаемый чип, а не съемную плашку. И зная китайцев, можно предположить, что на такой плате может собираться вообще что угодно, даже не очень подходящее, но позволяющее сэкономить.

Вероятно нет второй библиотеки на другом диске. В стиме, Steam - Настройки - Хранилище, Добавить диск.

Hidden text

Забавно конечно. Как минимум на Ростелекоме проще найти что резольвится, чем то что не резольвится. Даже смена днс (+ flushdns) на всякие 1.1.1.1 / 8.8.8.8 не помогает.

google.ru

dns.yandex.ru

И тем не менее, накопители SSD объёмом от 1 Тб всё ещё весьма недёшевы

HDD 1TB - 4-5к рублей, SSD 1TB - от 6.5к рублей (если не учитывать ADATA за 4.5к) на я.маркете. Неподъёмная разница в 2.5к рублей - действительно важный аргумент, особенно для нищих айтишников.

Вот и дожили до времён, когда даже notepad не стартует мгновенно.

Ждём теперь блокировку гитхаба?

Firefox, Vivaldi, Opera, Я.Браузер, Brave и сам Edge есть в Microsoft Store.

Скорее важно уточнить - это приватный ShadowSocks на своём VPS или просто какой-то публичный из интернета. Все публичные SS (и не SS) рано или поздно перебанят тупо по IP, вне зависимости от того 2022 или 2049.

Справедливо. Но я жирный текст рассматривал как визуальный якорь. Заголовок в этом случае читается целиком, по остальным пунктам глазами сначала вычленяются интересующие пункты, а детализация по мере необходимости - чтобы решить проблему перегрузки лишней информацией.

А если структурировать?

Горячей воды не будет!

Период: с 10 по 15 июня

Причина: ежегодный профилактический ремонт теплосетей

По вопросам обращаться: ооо ук1, тел. 123-123-123

Кроме прикладного ПО есть ещё и бесчисленное количество драйверов, которые никогда не будут писать под старое железо. Поэтому, вероятно, планируется, что первые доли процентов "armdows" возможны в ноутбучном сегменте через предустановленные оем-версии, ибо ждать пока подтянутся производители нового железа и умрёт старое придётся долго. Однако даже с винбуком на арм, с потребностями, которые бы покрыл и хромобук, но когда нет гарантии что воткнутая железка не заведётся, ОС на арм будет не очень популярна.

BLOB — булевая переменная

Булевая - это true/false. Блобы - это массивы двоичных данных обычно.

А ну ещё забыл тоже достаточно частый вариант, с left join'ами (часто такое с представлениями (view) бывает). Тут у оракла есть возможность не только выкидывать сегмент таблицы, но даже выкидывать целые подзапросы из результирующего плана, если не нужны все поля.

DDL
create table CLIENTS as
select level as id, 'client '||level as name
  from dual
 connect by level <= 1000
/

ALTER TABLE CLIENTS
 ADD CONSTRAINT PK_CLIENTS
  PRIMARY KEY (ID)
/

create table PAYMENTS as
select c.ID * 10000 + p.PAY_ID as PAY_ID, c.ID as CLIENT_ID, 0 as PAY_SUM 
from CLIENTS c, (select level as pay_id from dual connect by level <= 100) p
/

ALTER TABLE PAYMENTS
 ADD CONSTRAINT PK_PAYMENTS
  PRIMARY KEY (PAY_ID)
/

CREATE INDEX IDX_PAYMENTS_CLIENT_ID ON PAYMENTS
(CLIENT_ID)
/

ALTER TABLE PAYMENTS
 ADD CONSTRAINT FK_PAYMENTS_CLIENT 
  FOREIGN KEY (CLIENT_ID) 
  REFERENCES CLIENTS (ID)
/

create or replace view V_PAYMENTS as
select P.*, C.NAME
  from PAYMENTS P
   left join CLIENTS C on P.CLIENT_ID = C.ID
/

BEGIN
  SYS.DBMS_STATS.GATHER_TABLE_STATS (
     OwnName           => USER
    ,TabName           => 'PAYMENTS'
    ,Cascade           => TRUE);
  SYS.DBMS_STATS.GATHER_TABLE_STATS (
     OwnName           => USER
    ,TabName           => 'CLIENTS'
    ,Cascade           => TRUE);
END;
/

Вот чисто синтетический пример с таблицами PAYMENTS и CLIENTS, завёрнутые во вьюшку так, чтобы CLIENTS соединялась через left join. Теперь посмотрим планы запросов:

Со *:
select * 
  from V_PAYMENTS
 where client_id = 1
-------------------------------------------------------------------------------------------
| Id  | Operation                    | Name       | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |            |   100 |  2700 |    50   (2)| 00:00:01 |
|*  1 |  HASH JOIN OUTER             |            |   100 |  2700 |    50   (2)| 00:00:01 |
|*  2 |   TABLE ACCESS FULL          | PAYMENTS   |   100 |  1200 |    49   (3)| 00:00:01 |
|   3 |   TABLE ACCESS BY INDEX ROWID| CLIENTS    |     1 |    15 |     1   (0)| 00:00:01 |
|*  4 |    INDEX UNIQUE SCAN         | PK_CLIENTS |     1 |       |     0   (0)| 00:00:01 |
-------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   1 - access("P"."CLIENT_ID"="C"."ID"(+))
   2 - filter("P"."CLIENT_ID"=1)
   4 - access("C"."ID"(+)=1)

С конкретными полями:
select PAY_ID, PAY_SUM
  from V_PAYMENTS
 where client_id = 1
------------------------------------------------------------------------------
| Id  | Operation         | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |          |   100 |  1200 |    49   (3)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| PAYMENTS |   100 |  1200 |    49   (3)| 00:00:01 |
------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   1 - filter("P"."CLIENT_ID"=1)

Как видите во втором случае оракл полностью исключил таблицу CLIENTS из запроса. Конечно, физического смысла в такой архитектуре нет, но в жизни варианты могут быть намного сложнее и обширнее.

На самом деле есть случай, когда извлекаемые и используемые в соединении с другими таблицами целиком находятся в одном составном индексе. В этом случае оракл может вообще не обращаться к сегменту таблицы, если не требуется дополнительных полей. И тут разница уже будет - в случае со * это будет "index scan + table access", в случае выбора только проиндексированного поля - только "index scan" без обращения к таблице. Плюс ещё бывают поля с *LOB'ами которые ещё в одном сегменте находятся и могут не требоваться в данном конкретном запросе.

Запрос со *:
-----------------------------------------------------------------------------------------------------------------------
| Id  | Operation                                  | Name     | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
-----------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                           |          |     1 |    71 |     4   (0)| 00:00:01 |       |       |
|   1 |  PARTITION LIST SINGLE                     |          |     1 |    71 |     4   (0)| 00:00:01 |   KEY |   KEY |
|   2 |   TABLE ACCESS BY LOCAL INDEX ROWID BATCHED| TBL1     |     1 |    71 |     4   (0)| 00:00:01 |   KEY |   KEY |
|*  3 |    INDEX RANGE SCAN                        | IDX_TBL1 |     1 |       |     3   (0)| 00:00:01 |   KEY |   KEY |
-----------------------------------------------------------------------------------------------------------------------

Запрос с полем:
--------------------------------------------------------------------------------------------------
| Id  | Operation             | Name     | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
--------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT      |          |     1 |    12 |     3   (0)| 00:00:01 |       |       |
|   1 |  PARTITION LIST SINGLE|          |     1 |    12 |     3   (0)| 00:00:01 |   KEY |   KEY |
|*  2 |   INDEX RANGE SCAN    | IDX_TBL1 |     1 |    12 |     3   (0)| 00:00:01 |   KEY |   KEY |
--------------------------------------------------------------------------------------------------

Без чтения планов в оракле оптимизировать что-то невозможно. Поэтому любые советы по оптимизации по хорошему нужно сопровождать демонстрацией плана запросов, например как это делал @xtender в своих статьях на orasql.org.

Что касается CTE в оракле, то использовать их нужно с умом - они могут материализовываться в отдельную временную таблицу, а могут и инлайниться, встраиваюсь в запрос таким образом, как будто CTE и нет вообще, форсированно этим можно управлять соответствующими хинтами MATERIALIZE и INLINE соответственно. CTE c материализацией часто используется для следующей цели - допустим у нас есть тяжелый подзапрос с большим количеством соединений, возвращающий очень малое количество строк. И этот подзапрос нужно связать с другим сложным подзапросом или представлением - чтобы оракл не пытался объединить эти две части, ломая хорошо оптимизированные подзапросы, которые вернут условно по три строчки за пол секунды каждый, в один мегазапрос с кучей рейндж или фулл сканов, который будет работать пол часа. Поэтому надо чётко понимать, что заинлайненный СТЕ - это просто декорация, а материализованный - временная таблица, в которую выгружены все данные из подзапроса СТЕ. В вашем случае без CTE вероятно как раз и родился такой мегазапрос, который отъедал temp на группировках/сортировках, а переписав его на CTE вы материализовали какую-то его часть в отдельный подзапрос, который выполнился отдельно и выгрузился во временную таблицу и дальше уже использовались только результирующие строки из него.

Думается мне красивых имён аккаунтов хватит ещё на десяток подобных новостей.

Ещё в школе наткнулся на отличную русскоязычную справку в Турбо Паскале с гиперссылками и примерами, что сразу сподвигло изучать язык и программирование в частности даже за пределами преподаваемого на уроках. Думаю если бы не это, то я бы и не стал программистом.

Это уже из статьи видно, не "смешной милый котик дарит цветок", а кот с цветком по факту.

А CTE разве не будет считаться подзапросом? А ещё у вас выпали IP адреса, у которых было меньше 3-х посещений.

Информация

В рейтинге
Не участвует
Откуда
Пермь, Пермский край, Россия
Дата рождения
Зарегистрирован
Активность

Специализация

Fullstack Developer, Software Architect
Lead
Oracle
Oracle PL/SQL
C#
WPF
XAML
.NET