Все технические форумы на одном сайте Удобный поиск информации с популярных форумов в одном месте
Вопрос: Оптимизация boolean

Таблица:
Код

DELIMITER $$

CREATE TABLE `test` (
  `id` int(7) NOT NULL AUTO_INCREMENT,
  `val` int(7) NOT NULL DEFAULT '0',
  `bool` tinyint(1) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  INDEX(`val`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 $$

CREATE DEFINER=`root`@`localhost` PROCEDURE `fill_test`()
BEGIN
    DECLARE `v_i` BIGINT( 20 ) UNSIGNED DEFAULT 1e6 ;

    WHILE ( `v_i` > 0 ) DO
        SET `v_i` = `v_i` - 1 ;
        
        INSERT INTO
            `test`
        SET
                `val` = rand( ) * 10000 ,
                `bool` = rand( ) * 2 ;
    END WHILE ;
END $$

CALL `fill_test`( ) $$

DELIMITER ;


Запрос:
Код

SET profiling = true ;
SELECT
    `t1`.*
FROM
    `test` AS `t1`
WHERE
    ( `t1`.`val` > 1 ) ;
SHOW PROFILES ;

-- выводит 0.05080000

EXPLAIN
SELECT
    `t1`.*
FROM
    `test` AS `t1`
WHERE
    ( `t1`.`val` > 1 ) ;

/*
Выводит:
# id, select_type, table, type, possible_keys, key, key_len, ref, rows, Extra
1, SIMPLE, t1, ALL, val, , , , 1000000, Using where
*/


Запрос:
Код

SET profiling = true ;
SELECT
    `t1`.*
FROM
    `test` AS `t1`
WHERE
    ( `t1`.`bool` IS true ) ;
SHOW PROFILES ;

-- выводит 0.0.05997800

EXPLAIN
SELECT
    `t1`.*
FROM
    `test` AS `t1`
WHERE
    ( `t1`.`bool` IS true ) ;
/*
Выводит: 
# id, select_type, table, type, possible_keys, key, key_len, ref, rows, Extra
1, SIMPLE, t1, ALL, , , , , 1000000, Using where
*/


В обоих случаях выводит: "Using where" и время выполнения запроса с индексом и с полным перебором отличается всего на 15%.

Как оптимизировать значение типа BOOLEAN ( 1|0 ) = TINYINT( 1 )?
Вроде бы, дело не в энтропии значений, получается.

Это сообщение отредактировал(а) tishaishii - 11.12.2016, 12:47
Ответ:
_zorn_, Не о чем тут разбираться, "возитьса". Ответ на вопрос дан (Хоть и оформлен как вопрос и совсем не разжёван). Для низкоселективных предикатов индексный доступ по B-Tree индексам не эффективен. B-Tree так работает. Bitmap индексов в MySQL нет. Все. Тут больше не о чем говорить, нечего понимать. К экспертам ходить не надо.

Это сообщение отредактировал(а) Zloxa - 21.12.2016, 21:27
Вопрос: С чем связана такая дискриминация BOOLEAN?

Все условно-неявные конвертации выполняются отлично. Кроме boolean.
select '' || cast( 1 as SMALLINT ) from rdb$database;
select '' || cast( 1 as INTEGER ) from rdb$database;
select '' || cast( 1 as BIGINT ) from rdb$database;
select '' || cast( TRUE as BOOLEAN ) from rdb$database; -- Overflow occurred during data type conversion.
                                                        -- conversion error from string "BOOLEAN".
select '' || cast( 1.1 as FLOAT ) from rdb$database;
select '' || cast( 1.1 as DOUBLE PRECISION ) from rdb$database;
select '' || cast( 1.1 as NUMERIC(3,3) ) from rdb$database;
select '' || cast( 1.1 as DECIMAL(3,3) ) from rdb$database;
select '' || cast( '2015-01-01' as DATE ) from rdb$database;
select '' || cast( '10:51:59' as TIME ) from rdb$database;
select '' || cast( '2015-01-01 10:51:59' as TIMESTAMP ) from rdb$database;
select '' || cast( 'char text' as CHAR(20) ) from rdb$database;
select '' || cast( 'varchar text' as VARCHAR(20) ) from rdb$database;
select '' || cast( 'blob text' as BLOB ) from rdb$database;

А вот так нормально:
select cast( TRUE as varchar(20) ) from rdb$database;
Ответ: Мимопроходящий,

VARCHAR(14) только.
Вопрос: CREATE TYPE Boolean

Собственно в чем дело - есть старая программа на Access. Древняя, огромная и дурнонаписанная. Но более-менее работает. Табличная часть разбросана по разным mdb-шкам. Хочется все таблицы из mdb-шек перетащить на MS SQL. Запросы там не дюже крутонавороченные - через присоединенные таблицы работать будет. Пока основная из предвидимых проблем связана с полями типа Boolean. Просмотреть все их включения в коде и программе - нереально. А тупо использовать bit нельзя, так как возможны ошибки, ибо 1<>True. Соответственно выходит, что на основе bit нужно создать свой тип Boolean, который будет работать именно как Access-овский.

То что это можно сделать с помощью CREATE TYPE и CLR я понимаю, но никогда прежде это делать не приходилось... Может у кого есть полноценный пример создания хоть какого-то типа подобным образом? Чтобы поменьше времени на разборки ушло...
Ответ:
Glory
AndrF
Таблицы будут жить на нем.

А также при работе сервера и программы используются процессор, оперативная память и жесткий диск. Так что спросить еще можно в форуме по настройке оборудования...


Меня вообще-то интересовал конкретный вопрос взаимодействия Access-a и MS SQL, с которым, как я считал, возможны проблемы.

В итоге пока выяснил что есть одна проблема, но вполне решаемая - полям bit надо запретить NULL значения.
Вопрос: Не срабатывае boolean индекс при false

Подскажите почему не срабатывает boolean индекс при выборке false ? Я уже даже добавил отрицательный индекс и все равно идет Seq Scan. Vacuum Analyze делал. 9.5 версия.

prometheus=# \d+ trx;
                                                           Table "public.trx"
     Column      |            Type             |                    Modifiers                     | Storage | Stats target | Description
-----------------+-----------------------------+--------------------------------------------------+---------+--------------+-------------
 id              | integer                     | not null default nextval('trx_id_seq'::regclass) | plain   |              |
 block_id        | integer                     |                                                  | plain   |              |
 trx_id          | integer                     |                                                  | plain   |              |
 version         | integer                     |                                                  | plain   |              |
 index           | integer                     |                                                  | plain   |              |
 lock_time       | bigint                      |                                                  | plain   |              |
 size            | integer                     |                                                  | plain   |              |
 time            | integer                     |                                                  | plain   |              |
 inputs_count    | integer                     |                                                  | plain   |              |
 outputs_count   | integer                     |                                                  | plain   |              |
 mem_pool        | boolean                     | default false                                    | plain   |              |
 total_in_value  | bigint                      | default 0                                        | plain   |              |
 total_out_value | bigint                      | default 0                                        | plain   |              |
 est_out_value   | bigint                      | default 0                                        | plain   |              |
 fee             | bigint                      | default 0                                        | plain   |              |
 created_at      | timestamp without time zone |                                                  | plain   |              |
Indexes:
    "trx_pkey" PRIMARY KEY, btree (id)
    "index_trx_on_block_id" btree (block_id)
    "index_trx_on_mem_pool" btree (mem_pool)
    "index_trx_on_trx_id" btree (trx_id)
    "not_mempool_index" btree (mem_pool) WHERE mem_pool = false

prometheus=# explain select count(id) from trx where mem_pool = true;
                                          QUERY PLAN
----------------------------------------------------------------------------------------------
 Aggregate  (cost=1642.78..1642.79 rows=1 width=4)
   ->  Index Scan using index_trx_on_mem_pool on trx  (cost=0.57..1554.76 rows=35210 width=4)
         Index Cond: (mem_pool = true)
         Filter: mem_pool
(4 rows)

prometheus=# explain select count(id) from trx where mem_pool = false;
                              QUERY PLAN
-----------------------------------------------------------------------
 Aggregate  (cost=3276148.89..3276148.90 rows=1 width=4)
   ->  Seq Scan on trx  (cost=0.00..2982819.13 rows=117331903 width=4)
         Filter: (NOT mem_pool)
(3 rows)
Ответ:
vyegorov
qwwq,

А можно подробнее про две техники? (ссылками на статьи было бы замечательно.)
да примитивно:

1. с очередями на уникъю.
2. без уникъю, с джобом [тикером] подбора кучи , заменой подобранного на 1 свежую запись с SUM().

-- 1-е -- стандарт вообще.
-- 2.-е даже 1с умеют.

я 2 делал без тикера, но с дополнительной нагрузкой на вставку . лочил no wait то, что было свободно, и подбирал в общую кучку. понятно, что это затратнее разделения труда. правда я не каунты считал, а карту срезов для отложенного сбора статистики составлял.
Вопрос: измерение по полю тип boolean - два значения True

Доброго времени суток.

Есть измерение по полю тип boolean.
При просмотре измерения вижу значения

- True
- True
- Unknown

Одно из True работает как True, другое как False.

Кто виноват? И что делать?

Спасибо.
Ответ: StarikNavy,
Проверить что? и там значение False?
Вопрос: Как сравнить скорость работы запроса ДО и ПОСЛЕ оптимизации?

Собственно, есть БД. Оптимизацией занимаюсь первый раз. Есть запрос, который работает с несколькими таблицами. Хочу грамотно организовать индексы, статистику, запрос... Читаю мануалы. Но хотелось бы проверить эффективность работы точно, а не по отзывам пользователей, которые сидят этажом ниже.
Бэкапить старую версию БД, а потом восстановить для сравнения после оптимизации как-то костыльно.
Есть варианты?

SQL Server, Management Studio 2012
Ответ:
Сообщение от mDanilov
А если в рамках оптимизации речь идет об объединении нескольких больших таблиц в одну?
Что мешает, если так уж нужно, сделать такое объединение в этом же скрипте?
Вопрос: PostgreSQL оптимизация view

Коллеги, добрый день!
Осознаю, что в моем запросе есть "недочеты" . Прошу помочь с оптимизацией.

CREATE OR REPLACE VIEW all_tracing AS
SELECT smtp_mail_from, smtp_rcpt_to FROM tb_msg_tracing_0 WHERE delivery_status = 'sent' except
(
SELECT smtp_mail_from, smtp_rcpt_to FROM tb_msg_tracing_1 WHERE delivery_status = 'sent' union
SELECT smtp_mail_from, smtp_rcpt_to FROM tb_msg_tracing_2 WHERE delivery_status = 'sent' union
...
...
...
SELECT smtp_mail_from, smtp_rcpt_to FROM tb_msg_tracing_1534 WHERE delivery_status = 'sent' union
SELECT smtp_mail_from, smtp_rcpt_to FROM tb_msg_tracing_1535 WHERE delivery_status = 'sent'
);

ЗЫ. SQL владею на уровне совсем простах запросов
Ответ: Коллеги, добрый день!
Осознаю, что в моем запросе есть "недочеты" . Прошу помочь с оптимизацией.

CREATE OR REPLACE VIEW all_tracing AS
SELECT smtp_mail_from, smtp_rcpt_to FROM tb_msg_tracing_0 WHERE delivery_status = 'sent' except
(
SELECT smtp_mail_from, smtp_rcpt_to FROM tb_msg_tracing_1 WHERE delivery_status = 'sent' union
SELECT smtp_mail_from, smtp_rcpt_to FROM tb_msg_tracing_2 WHERE delivery_status = 'sent' union
...
...
...
SELECT smtp_mail_from, smtp_rcpt_to FROM tb_msg_tracing_1534 WHERE delivery_status = 'sent' union
SELECT smtp_mail_from, smtp_rcpt_to FROM tb_msg_tracing_1535 WHERE delivery_status = 'sent'
);

ЗЫ. SQL владею на уровне совсем простах запросов
Вопрос: Оптимизация фильтра

Здравствуйте.
Есть такая простенькая база хешей рутрекера: yadi.sk/d/FN1x5mjhkAN63
В 2003-м формате, чтобы у всех открывалась.
Одна таблица (ну почти), одна форма.
Проблема: фильтр в форме, он же поиск, занимает примерно 10 секунд, что некоторым кажется много.
Понятно, что 1625973 записи это не так уж и мало, но может есть какой-нибудь манёвр для оптимизации, про который я забыл?
Ответ: NBjHCBrc6KlSObm,
вы, кажется , спрашивали - "как оптимизировать", я вам предложил один из вариантов, оптимизация на лицо время поиска с 20 сек, уменьшилось до 4 сек, а как адаптировать при этом поиск, чтобы искалось как Like "*aphex*twin*" у меня тут обсуждать даже желания нет, это уже дело техники (для меня , во всяком случае , прозрачно и не интересно)... если вы не состоянии додумать предложенный алгоритм, может другие вам помогут, если у них , конечно, будет желание ...
Вопрос: Вопрос по оптимизации

Доброй ночи

Озадачен таким вот вопросом, возможно сформулирован будет плоховато но я постараюсь донести суть.
Вопроc решил задать на профильном форуме - именно тут.

Mysql поддерживает огромного размера таблицы буквально перед тем как напечатать пост увидел тут свежее сообщение о том что mysql держит таблицу до 35 гб и вообще впал в уныние.

Всем известная открытая система для интернет магазинов opencart работает в связке с базой mysql. Над её созданием как я понимаю трудятся очень много людей явно не глупых.

Почему при количестве товаров в магазине они же равны количеству записей в наибольшей таблице больше 200 000 все это дело начинает так тормозить что все желание купить что либо в таком магазине попадает.
Индексы на таблицах стоят, магазин стоит на отдельном сервере никто на его ресурсы не претендует, в момент запуска высоконагруженного скрипта загрузка сервера показывает проц 100 проц память 10%.
На профильном форуме opencart чем только не допиливают систему доработками "ускорителями"
Когда просто пролистываешь магазин страницы грузятся то 2 секунды то 10.

Магазинов с записью больше 400 000 вообще не встречал.
Можете дать ссылки можно в личку чтобы тут рекламой не заниматься где действительно высоконагруженные проекты работают шустро.

Помогите советом куда копнуть в сторону оптимизации?
Пишем тз под новый проект и в связи вышеизложенным думаем кому отдавать его в работу либо на свободнораспространяемые базы (чего желаем) либо в коммерцию (чего не хочется, не факт что у них все будет хорошо).
Спасибо большое.
Ответ: eualexey,

Если готовы платить, то напишите в ЛС - - адрес вашего сайта и какую сумму готовы потратить на оптимизации.
Вопрос: Несколько слов об оптимизации БД TecDoc Transbase, сконвертированной в MySQL

Очень часто я слышу вопросы об оптимизации базы данных TecDoc Transbase в MySQL, мол почему так много весит база сконвертировання в MySQL (TecDoc-14Гб=MySQL-50Гб), а как там обстоит дело с индексами, конвертируются ли они при помощи вашего скрипта.

Сразу отмечу: Transbase (на которой стоит TecDoc) это не MySQL, и способ организации данных, индексирование у него отличается от способа хранения данных в MySQL. А отсюда и все различия.

Второе, это то что TecDoc это не такая себе "серебряная пуля" или "панацея от всех болезней", его тоже разрабатывают люди, и в нем тоже есть ошибки: ошибки в кросах, ошибки в программе, ошибки в базе. ТекДок не универсален (как и все в этом сером мире :) ), многое в нем заложено на будущее, многое используется не очень редко или вообще не используется.

А посему база ТекДок в том виде, в котором она есть и конвертируется требует оптимизации под задачи клиента
(Можно конечно заюзать базу так как она есть, купить выделенный сервер, залить 50-ти гиговую базу, написать свою оболочку и радоватся жизни, но смысл? )

Перед использованием базы данных ТекДок в своем приложении (инет магазине) клиент а соответственно разработчик, которого он нанимает, должны задать себе ряд вопросов:

1) что собой будет представлять проект: интернет магазин, оф-лайновый стол заказов, каталог запчастей
2) для кого проект предназначен (категория потребителей: авто-мастера, розничные покупатели, оптовики, менеджеры продаж....)
3) определение границ проекта
4) График выполнения работ
5) ВАЖНО! БЮДЖЕТ! (это пожалуй один из самых важных вопросов)
6) Планы на будущее (т.е планируется развитие проекта, или нет)

А коль тема у нас оптимизация, расмотрим пример на таблице артикулов TOF_ARTICLES
В "сыром" виде эта таблица занимает 736,127Кб (в МБ переведете сами)

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

Давайте попытаемся немного оптимизировать эту таблицу.

Исходя из ее структуры, видим, что в поле ART_ARTICLE_NR хранятся сами артикули, и их мы будем искать очень часто, а значит это поле нужно сделать индексным.

Еще у нас есть поле ART_CTM - выясняем, что поле это не используется ТекДоком и заложено на будущее для оптимизации поиска или как бытует мнение на форумах для оптимизации поиска (возможно). Удаляем это поле из базы данных.

После этих нескольких нехитрых действий, получаем следующую картину

Как видим, база данных с индексами уже занимает 129,366 Кб, что практически на 600 мб меньше. И это только после 2-х простых действий.

Соответственно и запрос выполняется намного быстрее, сотые доли секунды

Картинки можно посмотреть здесь

Вот, так вот на примере только одной таблицы TOF_ARTICLES мы увидели как нужно "доводить до ума" нашу базу TecDoc
Ответ: Всем спасибо, что навели на мысль, хоть и не ответили!
Так же отдельное спасибо за подробное описание полей с указанием типов - помогло понять проблему!

Короче, вышел из ситуации так:
(tof_ENGINES.ENG_DRILLING CAST varchar(10)) AS DRILLING
Возвращает строку!
Реально возвращает. Потом преобразуешь уже в 1С как хочешь.
PS. Пробовал умножить на 1000 и преобразовать в интеджер - не вышло.