<?xml version="1.0" encoding="utf-8" ?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:tt="http://teletype.in/" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/"><title>Alexander Rodionov IT</title><author><name>Alexander Rodionov IT</name></author><id>https://teletype.in/atom/devguru</id><link rel="self" type="application/atom+xml" href="https://teletype.in/atom/devguru?offset=0"></link><link rel="alternate" type="text/html" href="https://blog.devgu.ru/?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=devguru"></link><link rel="next" type="application/rss+xml" href="https://teletype.in/atom/devguru?offset=10"></link><link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></link><updated>2026-04-15T16:27:13.132Z</updated><entry><id>devguru:mysql-count-vs-sum</id><link rel="alternate" type="text/html" href="https://blog.devgu.ru/mysql-count-vs-sum?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=devguru"></link><title>MySQL count VS sum</title><published>2021-01-28T08:12:57.786Z</published><updated>2021-01-28T08:12:57.786Z</updated><tt:hashtag>mysql</tt:hashtag><tt:hashtag>sql</tt:hashtag><tt:hashtag>оптимизация_запросов</tt:hashtag><summary type="html">Небольшое сравнение двух способов посчитать кол-во записей.</summary><content type="html">
  &lt;p&gt;Небольшое сравнение двух способов посчитать кол-во записей.&lt;/p&gt;
  &lt;p&gt;Табличка:&lt;/p&gt;
  &lt;pre&gt;mysql&amp;gt; show create table mobile_stat_device\G
*************************** 1. row ***************************
       Table: mobile_stat_device
Create Table: CREATE TABLE &amp;#x60;mobile_stat_device&amp;#x60; (
  &amp;#x60;id&amp;#x60; int unsigned NOT NULL AUTO_INCREMENT,
  &amp;#x60;deviceUuid&amp;#x60; char(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT &amp;#x27;Unique device ID&amp;#x27;,
  &amp;#x60;deviceUuidHash&amp;#x60; int unsigned GENERATED ALWAYS AS (crc32(&amp;#x60;deviceUuid&amp;#x60;)) STORED NOT NULL,
  &amp;#x60;createdAt&amp;#x60; datetime NOT NULL COMMENT &amp;#x27;Inserting date&amp;#x27;,
  PRIMARY KEY (&amp;#x60;id&amp;#x60;),
  UNIQUE KEY &amp;#x60;deviceUuid_udx&amp;#x60; (&amp;#x60;deviceUuidHash&amp;#x60;,&amp;#x60;deviceUuid&amp;#x60;),
  KEY &amp;#x60;deviceUuidHash_idx&amp;#x60; (&amp;#x60;deviceUuidHash&amp;#x60;)
) ENGINE=InnoDB AUTO_INCREMENT=2490316 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
1 row in set (0.00 sec)
&lt;/pre&gt;
  &lt;p&gt;Старый добрый &lt;code&gt;count&lt;/code&gt;:&lt;/p&gt;
  &lt;pre&gt;mysql&amp;gt; select count(1) from mobile_stat_device\G
*************************** 1. row ***************************
count(1): 2097152
1 row in set (2.20 sec)
&lt;/pre&gt;
  &lt;p&gt;Старый добрый &lt;code&gt;sum&lt;/code&gt;:&lt;/p&gt;
  &lt;pre&gt;mysql&amp;gt; select sum(1) from mobile_stat_device\G
*************************** 1. row ***************************
sum(1): 2097152
1 row in set (0.97 sec)
&lt;/pre&gt;
  &lt;p&gt;&lt;strong&gt;SUM быстрее COUNT более чем в два раза.&lt;/strong&gt;&lt;/p&gt;
  &lt;p&gt;При том, что планы выполнения совпадают до буквы.&lt;/p&gt;
  &lt;pre&gt;mysql&amp;gt; explain format=json select count(1) from mobile_stat_device\G
*************************** 1. row ***************************
EXPLAIN: {
  &amp;quot;query_block&amp;quot;: {
    &amp;quot;select_id&amp;quot;: 1,
    &amp;quot;cost_info&amp;quot;: {
      &amp;quot;query_cost&amp;quot;: &amp;quot;213393.07&amp;quot;
    },
    &amp;quot;table&amp;quot;: {
      &amp;quot;table_name&amp;quot;: &amp;quot;mobile_stat_device&amp;quot;,
      &amp;quot;access_type&amp;quot;: &amp;quot;index&amp;quot;,
      &amp;quot;key&amp;quot;: &amp;quot;deviceUuidHash_idx&amp;quot;,
      &amp;quot;used_key_parts&amp;quot;: [
        &amp;quot;deviceUuidHash&amp;quot;
      ],
      &amp;quot;key_length&amp;quot;: &amp;quot;4&amp;quot;,
      &amp;quot;rows_examined_per_scan&amp;quot;: 2088550,
      &amp;quot;rows_produced_per_join&amp;quot;: 2088550,
      &amp;quot;filtered&amp;quot;: &amp;quot;100.00&amp;quot;,
      &amp;quot;using_index&amp;quot;: true,
      &amp;quot;cost_info&amp;quot;: {
        &amp;quot;read_cost&amp;quot;: &amp;quot;4538.07&amp;quot;,
        &amp;quot;eval_cost&amp;quot;: &amp;quot;208855.00&amp;quot;,
        &amp;quot;prefix_cost&amp;quot;: &amp;quot;213393.07&amp;quot;,
        &amp;quot;data_read_per_join&amp;quot;: &amp;quot;318M&amp;quot;
      }
    }
  }
}
1 row in set, 1 warning (0.00 sec)&lt;/pre&gt;
  &lt;pre&gt;mysql&amp;gt; explain format=json select sum(1) from mobile_stat_device\G
*************************** 1. row ***************************
EXPLAIN: {
  &amp;quot;query_block&amp;quot;: {
    &amp;quot;select_id&amp;quot;: 1,
    &amp;quot;cost_info&amp;quot;: {
      &amp;quot;query_cost&amp;quot;: &amp;quot;213393.07&amp;quot;
    },
    &amp;quot;table&amp;quot;: {
      &amp;quot;table_name&amp;quot;: &amp;quot;mobile_stat_device&amp;quot;,
      &amp;quot;access_type&amp;quot;: &amp;quot;index&amp;quot;,
      &amp;quot;key&amp;quot;: &amp;quot;deviceUuidHash_idx&amp;quot;,
      &amp;quot;used_key_parts&amp;quot;: [
        &amp;quot;deviceUuidHash&amp;quot;
      ],
      &amp;quot;key_length&amp;quot;: &amp;quot;4&amp;quot;,
      &amp;quot;rows_examined_per_scan&amp;quot;: 2088550,
      &amp;quot;rows_produced_per_join&amp;quot;: 2088550,
      &amp;quot;filtered&amp;quot;: &amp;quot;100.00&amp;quot;,
      &amp;quot;using_index&amp;quot;: true,
      &amp;quot;cost_info&amp;quot;: {
        &amp;quot;read_cost&amp;quot;: &amp;quot;4538.07&amp;quot;,
        &amp;quot;eval_cost&amp;quot;: &amp;quot;208855.00&amp;quot;,
        &amp;quot;prefix_cost&amp;quot;: &amp;quot;213393.07&amp;quot;,
        &amp;quot;data_read_per_join&amp;quot;: &amp;quot;318M&amp;quot;
      }
    }
  }
}
1 row in set, 1 warning (0.00 sec)&lt;/pre&gt;
  &lt;tt-tags&gt;
    &lt;tt-tag name=&quot;mysql&quot;&gt;#mysql&lt;/tt-tag&gt;
    &lt;tt-tag name=&quot;sql&quot;&gt;#sql&lt;/tt-tag&gt;
    &lt;tt-tag name=&quot;оптимизация_запросов&quot;&gt;#оптимизация_запросов&lt;/tt-tag&gt;
  &lt;/tt-tags&gt;

</content></entry><entry><id>devguru:mysql-auto-increment</id><link rel="alternate" type="text/html" href="https://blog.devgu.ru/mysql-auto-increment?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=devguru"></link><title>AUTO_INCREMENT в MySQL</title><published>2021-01-22T08:19:58.597Z</published><updated>2021-01-22T08:21:14.108Z</updated><category term="my-sql" label="MySQL"></category><tt:hashtag>mysql</tt:hashtag><tt:hashtag>оптимизация_запросов</tt:hashtag><summary type="html">Казалось бы, что может быть проще, чем автоинкремент в mysql. Но и с ним есть подводные камни и грабли, которые лучше знать и учитывать при проектировании баз данных.</summary><content type="html">
  &lt;p&gt;Казалось бы, что может быть проще, чем автоинкремент в mysql. Но и с ним есть подводные камни и грабли, которые лучше знать и учитывать при проектировании баз данных.&lt;/p&gt;
  &lt;p&gt;Создадим тестовую табличку:&lt;/p&gt;
  &lt;pre&gt;mysql&amp;gt; create table test_ai(
    -&amp;gt;     id int primary key not null auto_increment,
    -&amp;gt;     alias varchar(255) not null,
    -&amp;gt;     unique index (alias)
    -&amp;gt; );
Query OK, 0 rows affected (0.04 sec)&lt;/pre&gt;
  &lt;p&gt;Главное, что в ней есть - это уникальный ключ, по полю alias&lt;/p&gt;
  &lt;p&gt;Вставим три записи&lt;/p&gt;
  &lt;pre&gt;mysql&amp;gt; insert into test_ai(alias) values (&amp;#x27;alias1&amp;#x27;), (&amp;#x27;alias2&amp;#x27;), (&amp;#x27;alias3&amp;#x27;);
Query OK, 3 rows affected (0.00 sec)&lt;/pre&gt;
  &lt;p&gt;Посмотрим значение auto_increment в табличке&lt;/p&gt;
  &lt;pre&gt;mysql&amp;gt; show create table test_ai\G
*************************** 1. row ***************************
       Table: test_ai
Create Table: CREATE TABLE &amp;#x60;test_ai&amp;#x60; (
  &amp;#x60;id&amp;#x60; int NOT NULL AUTO_INCREMENT,
  &amp;#x60;alias&amp;#x60; varchar(255) NOT NULL,
  PRIMARY KEY (&amp;#x60;id&amp;#x60;),
  UNIQUE KEY &amp;#x60;alias&amp;#x60; (&amp;#x60;alias&amp;#x60;)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci&lt;/pre&gt;
  &lt;p&gt;Всё вроде верно. Мы вставили 3 записи и следующее значение id будет равно 4.&lt;/p&gt;
  &lt;p&gt;&lt;strong&gt;Теперь начинается интересное.&lt;/strong&gt; Попробуем выполнить такую же вставку что и предыдущая.&lt;/p&gt;
  &lt;pre&gt;mysql&amp;gt; insert into test_ai(alias) values (&amp;#x27;alias1&amp;#x27;), (&amp;#x27;alias2&amp;#x27;), (&amp;#x27;alias3&amp;#x27;);
ERROR 1062 (23000): Duplicate entry &amp;#x27;alias1&amp;#x27; for key &amp;#x27;test_ai.alias&amp;#x27;&lt;/pre&gt;
  &lt;p&gt;Ожидаемо, получим ошибку. Посмотрим опять на значение auto_increment&lt;/p&gt;
  &lt;pre&gt;mysql&amp;gt; show create table test_ai\G
*************************** 1. row ***************************
       Table: test_ai
Create Table: CREATE TABLE &amp;#x60;test_ai&amp;#x60; (
  &amp;#x60;id&amp;#x60; int NOT NULL AUTO_INCREMENT,
  &amp;#x60;alias&amp;#x60; varchar(255) NOT NULL,
  PRIMARY KEY (&amp;#x60;id&amp;#x60;),
  UNIQUE KEY &amp;#x60;alias&amp;#x60; (&amp;#x60;alias&amp;#x60;)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.01 sec)&lt;/pre&gt;
  &lt;p&gt;&lt;strong&gt;7!&lt;/strong&gt; То есть mysql сначала увеличивает счетчик, а потом вставляет. Ладно, подавим ошибку и еще раз вставим.&lt;/p&gt;
  &lt;pre&gt;mysql&amp;gt; insert ignore into test_ai(alias) values (&amp;#x27;alias1&amp;#x27;), (&amp;#x27;alias2&amp;#x27;), (&amp;#x27;alias3&amp;#x27;);
Query OK, 0 rows affected, 3 warnings (0.02 sec)
Records: 3  Duplicates: 3  Warnings: 3&lt;/pre&gt;
  &lt;p&gt;И посмотрим.&lt;/p&gt;
  &lt;pre&gt;mysql&amp;gt; show create table test_ai\G
*************************** 1. row ***************************
       Table: test_ai
Create Table: CREATE TABLE &amp;#x60;test_ai&amp;#x60; (
  &amp;#x60;id&amp;#x60; int NOT NULL AUTO_INCREMENT,
  &amp;#x60;alias&amp;#x60; varchar(255) NOT NULL,
  PRIMARY KEY (&amp;#x60;id&amp;#x60;),
  UNIQUE KEY &amp;#x60;alias&amp;#x60; (&amp;#x60;alias&amp;#x60;)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)&lt;/pre&gt;
  &lt;p&gt;&lt;strong&gt;10!&lt;/strong&gt; То есть автоинкремент увеличивается в любом случае.&lt;/p&gt;
  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Попробуем replace.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
  &lt;pre&gt;mysql&amp;gt; replace into test_ai(alias) values (&amp;#x27;alias1&amp;#x27;), (&amp;#x27;alias2&amp;#x27;), (&amp;#x27;alias3&amp;#x27;);
Query OK, 6 rows affected (0.00 sec)
Records: 3  Duplicates: 3  Warnings: 0&lt;/pre&gt;
  &lt;pre&gt;mysql&amp;gt; show create table test_ai\G
*************************** 1. row ***************************
       Table: test_ai
Create Table: CREATE TABLE &amp;#x60;test_ai&amp;#x60; (
  &amp;#x60;id&amp;#x60; int NOT NULL AUTO_INCREMENT,
  &amp;#x60;alias&amp;#x60; varchar(255) NOT NULL,
  PRIMARY KEY (&amp;#x60;id&amp;#x60;),
  UNIQUE KEY &amp;#x60;alias&amp;#x60; (&amp;#x60;alias&amp;#x60;)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)&lt;/pre&gt;
  &lt;p&gt;Replace с одним валидным значением.&lt;/p&gt;
  &lt;pre&gt;mysql&amp;gt; replace into test_ai(alias) values (&amp;#x27;alias1&amp;#x27;), (&amp;#x27;alias2&amp;#x27;), (&amp;#x27;alias3&amp;#x27;), (&amp;#x27;alias4&amp;#x27;);
Query OK, 7 rows affected (0.01 sec)
Records: 4  Duplicates: 3  Warnings: 0&lt;/pre&gt;
  &lt;pre&gt;mysql&amp;gt; show create table test_ai\G
*************************** 1. row ***************************
       Table: test_ai
Create Table: CREATE TABLE &amp;#x60;test_ai&amp;#x60; (
  &amp;#x60;id&amp;#x60; int NOT NULL AUTO_INCREMENT,
  &amp;#x60;alias&amp;#x60; varchar(255) NOT NULL,
  PRIMARY KEY (&amp;#x60;id&amp;#x60;),
  UNIQUE KEY &amp;#x60;alias&amp;#x60; (&amp;#x60;alias&amp;#x60;)
) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)&lt;/pre&gt;
  &lt;p&gt;При этом ID поменялись, что логично. Но про replace и его принцип работы, как-нибудь в другой раз.&lt;/p&gt;
  &lt;pre&gt;mysql&amp;gt; select * from test_ai
    -&amp;gt; ;
+----+--------+
| id | alias  |
+----+--------+
| 13 | alias1 |
| 14 | alias2 |
| 15 | alias3 |
| 16 | alias4 |
+----+--------+&lt;/pre&gt;
  &lt;p&gt;И еще раз сделаем replace.&lt;/p&gt;
  &lt;pre&gt;mysql&amp;gt; replace into test_ai(alias) values (&amp;#x27;alias1&amp;#x27;), (&amp;#x27;alias2&amp;#x27;), (&amp;#x27;alias3&amp;#x27;), (&amp;#x27;alias4&amp;#x27;);
Query OK, 8 rows affected (0.02 sec)
Records: 4  Duplicates: 4  Warnings: 0&lt;/pre&gt;
  &lt;pre&gt;mysql&amp;gt; select * from test_ai;
+----+--------+
| id | alias  |
+----+--------+
| 17 | alias1 |
| 18 | alias2 |
| 19 | alias3 |
| 20 | alias4 |
+----+--------+&lt;/pre&gt;
  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Попробуем обработать ошибку вставки через &amp;#x27;on duplicate key update&amp;#x27;&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
  &lt;pre&gt;mysql&amp;gt; insert into test_ai(alias) values (&amp;#x27;alias1&amp;#x27;), (&amp;#x27;alias2&amp;#x27;), (&amp;#x27;alias3&amp;#x27;) on duplicate key update id = id;
Query OK, 0 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0
&lt;/pre&gt;
  &lt;pre&gt;mysql&amp;gt; show create table test_ai\G
*************************** 1. row ***************************
       Table: test_ai
Create Table: CREATE TABLE &amp;#x60;test_ai&amp;#x60; (
  &amp;#x60;id&amp;#x60; int NOT NULL AUTO_INCREMENT,
  &amp;#x60;alias&amp;#x60; varchar(255) NOT NULL,
  PRIMARY KEY (&amp;#x60;id&amp;#x60;),
  UNIQUE KEY &amp;#x60;alias&amp;#x60; (&amp;#x60;alias&amp;#x60;)
) ENGINE=InnoDB AUTO_INCREMENT=24 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci&lt;/pre&gt;
  &lt;p&gt;&lt;em&gt;&lt;strong&gt;Вывод:&lt;/strong&gt; не зависит успешно или неуспешно вставлены данные, в любом случае auto_increment будет ползти вверх. А значит, при достаточных объёмах вставляемых данных (с любым результатом) auto_increment  очень быстро может достичь максимального значения для первичного ключа. Кроме того, необходимо учитывать возможную неравномерность распределения значений первичного ключа, например, в случае если &lt;a href=&quot;https://blog.devgu.ru/mysql-offset-optimization&quot; target=&quot;_blank&quot;&gt;необходимости по нему итерироваться&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
  &lt;tt-tags&gt;
    &lt;tt-tag name=&quot;mysql&quot;&gt;#mysql&lt;/tt-tag&gt;
    &lt;tt-tag name=&quot;оптимизация_запросов&quot;&gt;#оптимизация_запросов&lt;/tt-tag&gt;
  &lt;/tt-tags&gt;

</content></entry><entry><id>devguru:mysql-offset-optimization</id><link rel="alternate" type="text/html" href="https://blog.devgu.ru/mysql-offset-optimization?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=devguru"></link><title>Оптимизация OFFSET в MySQL</title><published>2021-01-11T10:32:34.741Z</published><updated>2021-01-11T10:32:34.741Z</updated><category term="my-sql" label="MySQL"></category><tt:hashtag>mysql</tt:hashtag><tt:hashtag>sql</tt:hashtag><tt:hashtag>оптимизация_запросов</tt:hashtag><summary type="html">Штука вроде очевидная, но всё же стоит её записать.</summary><content type="html">
  &lt;p&gt;Штука вроде очевидная, но всё же стоит её записать.&lt;/p&gt;
  &lt;p&gt;В базах данных &lt;code&gt;offset&lt;/code&gt; работает так: выбираются первые записи, где кол-во выбираемых записей равно &lt;code&gt;offset+limit&lt;/code&gt;, потом записи до &lt;code&gt;offset&lt;/code&gt; отбрасываются и остаток уже возвращается в запросе. Покажу на примере.&lt;/p&gt;
  &lt;p&gt;Как всегда, любимая табличка &lt;code&gt;mobile_stat_device&lt;/code&gt;&lt;/p&gt;
  &lt;pre&gt;mysql&amp;gt; show create table mobile_stat_device\G
*************************** 1. row ***************************
       Table: mobile_stat_device
Create Table: CREATE TABLE &amp;#x60;mobile_stat_device&amp;#x60; (
  &amp;#x60;id&amp;#x60; int unsigned NOT NULL AUTO_INCREMENT,
  &amp;#x60;deviceUuid&amp;#x60; char(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT &amp;#x27;Unique device ID&amp;#x27;,
  &amp;#x60;deviceUuidHash&amp;#x60; int unsigned GENERATED ALWAYS AS (crc32(&amp;#x60;deviceUuid&amp;#x60;)) STORED NOT NULL,
  &amp;#x60;createdAt&amp;#x60; datetime NOT NULL COMMENT &amp;#x27;Inserting date&amp;#x27;,
  PRIMARY KEY (&amp;#x60;id&amp;#x60;),
  UNIQUE KEY &amp;#x60;deviceUuid_udx&amp;#x60; (&amp;#x60;deviceUuidHash&amp;#x60;,&amp;#x60;deviceUuid&amp;#x60;),
  KEY &amp;#x60;deviceUuidHash_idx&amp;#x60; (&amp;#x60;deviceUuidHash&amp;#x60;)
) ENGINE=InnoDB AUTO_INCREMENT=2490316 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci&lt;/pre&gt;
  &lt;p&gt;С большим количеством записей&lt;/p&gt;
  &lt;pre&gt;mysql&amp;gt; select count(1) from mobile_stat_device;
+----------+
| count(1) |
+----------+
|  2097152 |
+----------+&lt;/pre&gt;
  &lt;p&gt;Запрос, который выполняется почти секунду:&lt;/p&gt;
  &lt;pre&gt;mysql&amp;gt; select SQL_NO_CACHE * from mobile_stat_device order by id limit 10 offset 2050000;
+---------+--------------------------------------+----------------+---------------------+
| id      | deviceUuid                           | deviceUuidHash | createdAt           |
+---------+--------------------------------------+----------------+---------------------+
| 2377645 | 370f4d5e-519b-11eb-a85f-42010a9c0002 |     1792791173 | 2021-01-08 10:21:03 |
| 2377646 | 370f4d6c-519b-11eb-a85f-42010a9c0002 |     3206227716 | 2021-01-08 10:21:03 |
| 2377647 | 370f4d7b-519b-11eb-a85f-42010a9c0002 |     3766230312 | 2021-01-08 10:21:03 |
| 2377648 | 370f4d89-519b-11eb-a85f-42010a9c0002 |     2525345549 | 2021-01-08 10:21:03 |
| 2377649 | 370f4d98-519b-11eb-a85f-42010a9c0002 |     3387067681 | 2021-01-08 10:21:03 |
| 2377650 | 370f4da6-519b-11eb-a85f-42010a9c0002 |     2785299536 | 2021-01-08 10:21:03 |
| 2377651 | 370f4db5-519b-11eb-a85f-42010a9c0002 |     1202520612 | 2021-01-08 10:21:03 |
| 2377652 | 370f4dc3-519b-11eb-a85f-42010a9c0002 |     3937153461 | 2021-01-08 10:21:03 |
| 2377653 | 370f4dd2-519b-11eb-a85f-42010a9c0002 |     1015628201 | 2021-01-08 10:21:03 |
| 2377654 | 370f4de1-519b-11eb-a85f-42010a9c0002 |     2783037901 | 2021-01-08 10:21:03 |
+---------+--------------------------------------+----------------+---------------------+
10 rows in set, 1 warning (0.50 sec)&lt;/pre&gt;
  &lt;p&gt;С очень любопытным &lt;code&gt;explain&lt;/code&gt;:&lt;/p&gt;
  &lt;pre&gt;mysql&amp;gt; explain format=json select SQL_NO_CACHE * from mobile_stat_device order by id limit 10 offset 2050000\G
*************************** 1. row ***************************
EXPLAIN: {
  &amp;quot;query_block&amp;quot;: {
    &amp;quot;select_id&amp;quot;: 1,
    &amp;quot;cost_info&amp;quot;: {
      &amp;quot;query_cost&amp;quot;: &amp;quot;213695.60&amp;quot;
    },
    &amp;quot;ordering_operation&amp;quot;: {
      &amp;quot;using_filesort&amp;quot;: false,
      &amp;quot;table&amp;quot;: {
        &amp;quot;table_name&amp;quot;: &amp;quot;mobile_stat_device&amp;quot;,
        &amp;quot;access_type&amp;quot;: &amp;quot;index&amp;quot;,
        &amp;quot;key&amp;quot;: &amp;quot;PRIMARY&amp;quot;,
        &amp;quot;used_key_parts&amp;quot;: [
          &amp;quot;id&amp;quot;
        ],
        &amp;quot;key_length&amp;quot;: &amp;quot;4&amp;quot;,
        &amp;quot;rows_examined_per_scan&amp;quot;: 2050010,
        &amp;quot;rows_produced_per_join&amp;quot;: 2088550,
        &amp;quot;filtered&amp;quot;: &amp;quot;100.00&amp;quot;,
        &amp;quot;cost_info&amp;quot;: {
          &amp;quot;read_cost&amp;quot;: &amp;quot;4840.61&amp;quot;,
          &amp;quot;eval_cost&amp;quot;: &amp;quot;208855.00&amp;quot;,
          &amp;quot;prefix_cost&amp;quot;: &amp;quot;213695.61&amp;quot;,
          &amp;quot;data_read_per_join&amp;quot;: &amp;quot;318M&amp;quot;
        },
        &amp;quot;used_columns&amp;quot;: [
          &amp;quot;id&amp;quot;,
          &amp;quot;deviceUuid&amp;quot;,
          &amp;quot;deviceUuidHash&amp;quot;,
          &amp;quot;createdAt&amp;quot;
        ]
      }
    }
  }
}&lt;/pre&gt;
  &lt;p&gt;Для того, что бы отдать 680 байт mysql прочитал 318 мегабайт. Кол-во затронутых записей &lt;code&gt;rows_examined_per_scan = 2050010 = 2050000(offset) + 10(limit)&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;И что самое плохое в этом запросе - с увеличением &lt;code&gt;offset&lt;/code&gt; производительность и дальше будет деградировать.&lt;/p&gt;
  &lt;h3&gt;Как быть?&lt;/h3&gt;
  &lt;p&gt;В данном конкретном случае, можно воспользоваться тем, что id идут по порядку и переписать запрос так&lt;/p&gt;
  &lt;pre&gt;mysql&amp;gt; select SQL_NO_CACHE * from mobile_stat_device where id between 2377645 and 2377654 order by id;
+---------+--------------------------------------+----------------+---------------------+
| id      | deviceUuid                           | deviceUuidHash | createdAt           |
+---------+--------------------------------------+----------------+---------------------+
| 2377645 | 370f4d5e-519b-11eb-a85f-42010a9c0002 |     1792791173 | 2021-01-08 10:21:03 |
| 2377646 | 370f4d6c-519b-11eb-a85f-42010a9c0002 |     3206227716 | 2021-01-08 10:21:03 |
| 2377647 | 370f4d7b-519b-11eb-a85f-42010a9c0002 |     3766230312 | 2021-01-08 10:21:03 |
| 2377648 | 370f4d89-519b-11eb-a85f-42010a9c0002 |     2525345549 | 2021-01-08 10:21:03 |
| 2377649 | 370f4d98-519b-11eb-a85f-42010a9c0002 |     3387067681 | 2021-01-08 10:21:03 |
| 2377650 | 370f4da6-519b-11eb-a85f-42010a9c0002 |     2785299536 | 2021-01-08 10:21:03 |
| 2377651 | 370f4db5-519b-11eb-a85f-42010a9c0002 |     1202520612 | 2021-01-08 10:21:03 |
| 2377652 | 370f4dc3-519b-11eb-a85f-42010a9c0002 |     3937153461 | 2021-01-08 10:21:03 |
| 2377653 | 370f4dd2-519b-11eb-a85f-42010a9c0002 |     1015628201 | 2021-01-08 10:21:03 |
| 2377654 | 370f4de1-519b-11eb-a85f-42010a9c0002 |     2783037901 | 2021-01-08 10:21:03 |
+---------+--------------------------------------+----------------+---------------------+
10 rows in set, 1 warning (0.00 sec)
&lt;/pre&gt;
  &lt;p&gt;Explain:&lt;/p&gt;
  &lt;pre&gt;mysql&amp;gt; explain format=json select SQL_NO_CACHE * from mobile_stat_device where id between 2377645 and 2377654 order by id\G
*************************** 1. row ***************************
EXPLAIN: {
  &amp;quot;query_block&amp;quot;: {
    &amp;quot;select_id&amp;quot;: 1,
    &amp;quot;cost_info&amp;quot;: {
      &amp;quot;query_cost&amp;quot;: &amp;quot;2.57&amp;quot;
    },
    &amp;quot;ordering_operation&amp;quot;: {
      &amp;quot;using_filesort&amp;quot;: false,
      &amp;quot;table&amp;quot;: {
        &amp;quot;table_name&amp;quot;: &amp;quot;mobile_stat_device&amp;quot;,
        &amp;quot;access_type&amp;quot;: &amp;quot;range&amp;quot;,
        &amp;quot;possible_keys&amp;quot;: [
          &amp;quot;PRIMARY&amp;quot;
        ],
        &amp;quot;key&amp;quot;: &amp;quot;PRIMARY&amp;quot;,
        &amp;quot;used_key_parts&amp;quot;: [
          &amp;quot;id&amp;quot;
        ],
        &amp;quot;key_length&amp;quot;: &amp;quot;4&amp;quot;,
        &amp;quot;rows_examined_per_scan&amp;quot;: 10,
        &amp;quot;rows_produced_per_join&amp;quot;: 10,
        &amp;quot;filtered&amp;quot;: &amp;quot;100.00&amp;quot;,
        &amp;quot;cost_info&amp;quot;: {
          &amp;quot;read_cost&amp;quot;: &amp;quot;1.57&amp;quot;,
          &amp;quot;eval_cost&amp;quot;: &amp;quot;1.00&amp;quot;,
          &amp;quot;prefix_cost&amp;quot;: &amp;quot;2.57&amp;quot;,
          &amp;quot;data_read_per_join&amp;quot;: &amp;quot;1K&amp;quot;
        },
        &amp;quot;used_columns&amp;quot;: [
          &amp;quot;id&amp;quot;,
          &amp;quot;deviceUuid&amp;quot;,
          &amp;quot;deviceUuidHash&amp;quot;,
          &amp;quot;createdAt&amp;quot;
        ],
        &amp;quot;attached_condition&amp;quot;: &amp;quot;(&amp;#x60;test&amp;#x60;.&amp;#x60;mobile_stat_device&amp;#x60;.&amp;#x60;id&amp;#x60; between 2377645 and 2377654)&amp;quot;
      }
    }
  }
}&lt;/pre&gt;
  &lt;p&gt;Вот, стало значительно веселее.&lt;/p&gt;
  &lt;p&gt;Если необходимо пробежаться по всем записям таблички чтобы, например, сделать экспорт, то можно использовать условие &lt;code&gt;id &amp;gt; самого большого id прошлой выборки, но id &amp;lt;= самого большого id прошлой выборки + limit + 1&lt;/code&gt;. Условием остановки итераций будет значение &lt;code&gt;id &amp;gt;= максимального значения id&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;Запросы для отображения по страницам - для чего обычно и используют лимиты и офсеты, тут смысла не имеют из-за большого количества данных. Если же наложить какие-то внешние фильтры, уменьшив там самым кол-во выбираемых данных, то и offset будет работать быстро.&lt;/p&gt;
  &lt;tt-tags&gt;
    &lt;tt-tag name=&quot;mysql&quot;&gt;#mysql&lt;/tt-tag&gt;
    &lt;tt-tag name=&quot;sql&quot;&gt;#sql&lt;/tt-tag&gt;
    &lt;tt-tag name=&quot;оптимизация_запросов&quot;&gt;#оптимизация_запросов&lt;/tt-tag&gt;
  &lt;/tt-tags&gt;

</content></entry><entry><id>devguru:mysql-slow-sql-story</id><link rel="alternate" type="text/html" href="https://blog.devgu.ru/mysql-slow-sql-story?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=devguru"></link><title>MySQL. История одного медленного запроса</title><published>2021-01-08T11:38:07.217Z</published><updated>2021-01-08T11:39:29.678Z</updated><category term="my-sql" label="MySQL"></category><tt:hashtag>mysql</tt:hashtag><tt:hashtag>sql</tt:hashtag><tt:hashtag>оптимизация_запросов</tt:hashtag><summary type="html">SQL запросы иногда бывают не оптимизированы, из-за неправильного понимания механизмов работы</summary><content type="html">
  &lt;p&gt;SQL запросы иногда бывают не оптимизированы, из-за неправильного понимания механизмов работы&lt;/p&gt;
  &lt;p&gt;Есть вот такая табличка:&lt;/p&gt;
  &lt;pre&gt;mysql&amp;gt; show create table mobile_stat_device\G
*************************** 1. row ***************************
       Table: mobile_stat_device
Create Table: CREATE TABLE &amp;#x60;mobile_stat_device&amp;#x60; (
  &amp;#x60;id&amp;#x60; int unsigned NOT NULL AUTO_INCREMENT,
  &amp;#x60;deviceUuid&amp;#x60; char(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT &amp;#x27;Unique device ID&amp;#x27;,
  &amp;#x60;deviceUuidHash&amp;#x60; int unsigned GENERATED ALWAYS AS (crc32(&amp;#x60;deviceUuid&amp;#x60;)) STORED NOT NULL,
  &amp;#x60;createdAt&amp;#x60; datetime NOT NULL COMMENT &amp;#x27;Inserting date&amp;#x27;,
  PRIMARY KEY (&amp;#x60;id&amp;#x60;),
  UNIQUE KEY &amp;#x60;deviceUuid_udx&amp;#x60; (&amp;#x60;deviceUuidHash&amp;#x60;,&amp;#x60;deviceUuid&amp;#x60;),
  KEY &amp;#x60;deviceUuidHash_idx&amp;#x60; (&amp;#x60;deviceUuidHash&amp;#x60;)
) ENGINE=InnoDB AUTO_INCREMENT=2490316 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci&lt;/pre&gt;
  &lt;p&gt;Табличка с &lt;code&gt;uuid&lt;/code&gt; устройств. Для ускорения запросов добавлено поле  &lt;code&gt;deviceUuidHash&lt;/code&gt; и создан комбинированный уникальный индекс по полям &lt;code&gt;deviceUuidHash&lt;/code&gt; и &lt;code&gt;deviceUuid&lt;/code&gt;.&lt;/p&gt;
  &lt;p&gt;Кол-во записей в mobile_stat&lt;em&gt;_&lt;/em&gt;device чуть больше 2х миллионов:&lt;/p&gt;
  &lt;pre&gt;mysql&amp;gt; select count(1) from mobile_stat_device;
+----------+
| count(1) |
+----------+
|  2097152 |
+----------+
&lt;/pre&gt;
  &lt;p&gt;Нам необходимо выбрать &lt;code&gt;id&lt;/code&gt; для определенных &lt;code&gt;uuid&lt;/code&gt; устройств. Мой первый запрос выглядел вот так:&lt;/p&gt;
  &lt;pre&gt;mysql&amp;gt; select id, deviceUuid from mobile_stat_device where 
(deviceUuid = &amp;#x27;36fffc8d-519b-11eb-a85f-42010a9c0002&amp;#x27; and deviceUuidHash = crc32(deviceUuid)) or
(deviceUuid = &amp;#x27;36fffd73-519b-11eb-a85f-42010a9c0002&amp;#x27; and deviceUuidHash = crc32(deviceUuid));
+---------+--------------------------------------+
| id      | deviceUuid                           |
+---------+--------------------------------------+
| 2327645 | 36fffc8d-519b-11eb-a85f-42010a9c0002 |
| 2327653 | 36fffd73-519b-11eb-a85f-42010a9c0002 |
+---------+--------------------------------------+&lt;/pre&gt;
  &lt;p&gt;Посмотрев на &lt;code&gt;explain&lt;/code&gt;, я успокоился - индекс используется, ну и ладно&lt;/p&gt;
  &lt;pre&gt;
mysql&amp;gt; explain select id, deviceUuid from mobile_stat_device where (deviceUuid = &amp;#x27;36fffc8d-519b-11eb-a85f-42010a9c0002&amp;#x27; and deviceUuidHash=crc32(deviceUuid)) or (deviceUuid = &amp;#x27;36fffd73-519b-11eb-a85f-42010a9c0002&amp;#x27; and deviceUuidHash = crc32(deviceUuid));
+----+-------------+--------------------+------------+-------+---------------+----------------+---------+------+---------+----------+--------------------------+
| id | select_type | table              | partitions | type  | possible_keys | key            | key_len | ref  | rows    | filtered | Extra                    |
+----+-------------+--------------------+------------+-------+---------------+----------------+---------+------+---------+----------+--------------------------+
|  1 | SIMPLE      | mobile_stat_device | NULL       | index | NULL          | deviceUuid_udx | 148     | NULL | 2088550 |     1.99 | Using where; Using index |
+----+-------------+--------------------+------------+-------+---------------+----------------+---------+------+---------+----------+--------------------------+&lt;/pre&gt;
  &lt;p&gt;Я не обратил внимание на количество &lt;code&gt;rows&lt;/code&gt; в эксплейне. Точнее, когда данных мало, то и кол-во &lt;code&gt;rows&lt;/code&gt; приемлемое. Ошибочность запроса стала понятна только когда нагрузил данными табличку и еще раз проверил скорость запроса.&lt;/p&gt;
  &lt;p&gt;Вот тот же &lt;code&gt;explain&lt;/code&gt; в более информативном виде.&lt;/p&gt;
  &lt;pre&gt;
mysql&amp;gt; explain format=json select id, deviceUuid from mobile_stat_device where (deviceUuid = &amp;#x27;36fffc8d-519b-11eb-a85f-42010a9c0002&amp;#x27; and deviceUuidHash=crc32(deviceUuid)) or (deviceUuid = &amp;#x27;36fffd73-519b-11eb-a85f-42010a9c0002&amp;#x27; and deviceUuidHash = crc32(deviceUuid))\G
*************************** 1. row ***************************
EXPLAIN: {
  &amp;quot;query_block&amp;quot;: {
    &amp;quot;select_id&amp;quot;: 1,
    &amp;quot;cost_info&amp;quot;: {
      &amp;quot;query_cost&amp;quot;: &amp;quot;216917.41&amp;quot;
    },
    &amp;quot;table&amp;quot;: {
      &amp;quot;table_name&amp;quot;: &amp;quot;mobile_stat_device&amp;quot;,
      &amp;quot;access_type&amp;quot;: &amp;quot;index&amp;quot;,
      &amp;quot;key&amp;quot;: &amp;quot;deviceUuid_udx&amp;quot;,
      &amp;quot;used_key_parts&amp;quot;: [
        &amp;quot;deviceUuidHash&amp;quot;,
        &amp;quot;deviceUuid&amp;quot;
      ],
      &amp;quot;key_length&amp;quot;: &amp;quot;148&amp;quot;,
      &amp;quot;rows_examined_per_scan&amp;quot;: 2088550,
      &amp;quot;rows_produced_per_join&amp;quot;: 41562,
      &amp;quot;filtered&amp;quot;: &amp;quot;1.99&amp;quot;,
      &amp;quot;using_index&amp;quot;: true,
      &amp;quot;cost_info&amp;quot;: {
        &amp;quot;read_cost&amp;quot;: &amp;quot;212761.19&amp;quot;,
        &amp;quot;eval_cost&amp;quot;: &amp;quot;4156.21&amp;quot;,
        &amp;quot;prefix_cost&amp;quot;: &amp;quot;216917.41&amp;quot;,
        &amp;quot;data_read_per_join&amp;quot;: &amp;quot;6M&amp;quot;
      },
      &amp;quot;used_columns&amp;quot;: [
        &amp;quot;id&amp;quot;,
        &amp;quot;deviceUuid&amp;quot;,
        &amp;quot;deviceUuidHash&amp;quot;
      ],
      &amp;quot;attached_condition&amp;quot;: &amp;quot;(((&amp;#x60;test&amp;#x60;.&amp;#x60;mobile_stat_device&amp;#x60;.&amp;#x60;deviceUuid&amp;#x60; = &amp;#x27;36fffc8d-519b-11eb-a85f-42010a9c0002&amp;#x27;) and (&amp;#x60;test&amp;#x60;.&amp;#x60;mobile_stat_device&amp;#x60;.&amp;#x60;deviceUuidHash&amp;#x60; = crc32(&amp;#x60;test&amp;#x60;.&amp;#x60;mobile_stat_device&amp;#x60;.&amp;#x60;deviceUuid&amp;#x60;))) or ((&amp;#x60;test&amp;#x60;.&amp;#x60;mobile_stat_device&amp;#x60;.&amp;#x60;deviceUuid&amp;#x60; = &amp;#x27;36fffd73-519b-11eb-a85f-42010a9c0002&amp;#x27;) and (&amp;#x60;test&amp;#x60;.&amp;#x60;mobile_stat_device&amp;#x60;.&amp;#x60;deviceUuidHash&amp;#x60; = crc32(&amp;#x60;test&amp;#x60;.&amp;#x60;mobile_stat_device&amp;#x60;.&amp;#x60;deviceUuid&amp;#x60;))))&amp;quot;
    }
  }
}
&lt;/pre&gt;
  &lt;p&gt;О чём это говорит? Запрос пробегает по 2088550 записям и для ответа использует 41562. А так быть не должно. Где-то ошибка.&lt;/p&gt;
  &lt;p&gt;Внимательный читатель уже догадался где. Вот в этом условии - &lt;code&gt;and deviceUuidHash = crc32(deviceUuid)&lt;/code&gt;. Похоже, MySQL сначала вычисляет значение &lt;code&gt;crc32&lt;/code&gt; для всех записей, а потом уже, используя индекс, делается селект.&lt;/p&gt;
  &lt;p&gt;Переписанный запрос.&lt;/p&gt;
  &lt;pre&gt;mysql&amp;gt; explain format=json select id, deviceUuid from mobile_stat_device
where (deviceUuid = &amp;#x27;36fffc8d-519b-11eb-a85f-42010a9c0002&amp;#x27; and 
deviceUuidHash=crc32(&amp;#x27;36fffc8d-519b-11eb-a85f-42010a9c0002&amp;#x27;)) or 
(deviceUuid = &amp;#x27;36fffd73-519b-11eb-a85f-42010a9c0002&amp;#x27; and 
deviceUuidHash = crc32(&amp;#x27;36fffd73-519b-11eb-a85f-42010a9c0002&amp;#x27;))\G
*************************** 1. row ***************************
EXPLAIN: {
  &amp;quot;query_block&amp;quot;: {
    &amp;quot;select_id&amp;quot;: 1,
    &amp;quot;cost_info&amp;quot;: {
      &amp;quot;query_cost&amp;quot;: &amp;quot;0.85&amp;quot;
    },
    &amp;quot;table&amp;quot;: {
      &amp;quot;table_name&amp;quot;: &amp;quot;mobile_stat_device&amp;quot;,
      &amp;quot;access_type&amp;quot;: &amp;quot;range&amp;quot;,
      &amp;quot;possible_keys&amp;quot;: [
        &amp;quot;deviceUuid_udx&amp;quot;,
        &amp;quot;deviceUuidHash_idx&amp;quot;
      ],
      &amp;quot;key&amp;quot;: &amp;quot;deviceUuid_udx&amp;quot;,
      &amp;quot;used_key_parts&amp;quot;: [
        &amp;quot;deviceUuidHash&amp;quot;,
        &amp;quot;deviceUuid&amp;quot;
      ],
      &amp;quot;key_length&amp;quot;: &amp;quot;148&amp;quot;,
      &amp;quot;rows_examined_per_scan&amp;quot;: 2,
      &amp;quot;rows_produced_per_join&amp;quot;: 2,
      &amp;quot;filtered&amp;quot;: &amp;quot;100.00&amp;quot;,
      &amp;quot;using_index&amp;quot;: true,
      &amp;quot;cost_info&amp;quot;: {
        &amp;quot;read_cost&amp;quot;: &amp;quot;0.65&amp;quot;,
        &amp;quot;eval_cost&amp;quot;: &amp;quot;0.20&amp;quot;,
        &amp;quot;prefix_cost&amp;quot;: &amp;quot;0.85&amp;quot;,
        &amp;quot;data_read_per_join&amp;quot;: &amp;quot;320&amp;quot;
      },
      &amp;quot;used_columns&amp;quot;: [
        &amp;quot;id&amp;quot;,
        &amp;quot;deviceUuid&amp;quot;,
        &amp;quot;deviceUuidHash&amp;quot;
      ],
      &amp;quot;attached_condition&amp;quot;: &amp;quot;(((&amp;#x60;test&amp;#x60;.&amp;#x60;mobile_stat_device&amp;#x60;.&amp;#x60;deviceUuidHash&amp;#x60; = &amp;lt;cache&amp;gt;(crc32(&amp;#x27;36fffc8d-519b-11eb-a85f-42010a9c0002&amp;#x27;))) and (&amp;#x60;test&amp;#x60;.&amp;#x60;mobile_stat_device&amp;#x60;.&amp;#x60;deviceUuid&amp;#x60; = &amp;#x27;36fffc8d-519b-11eb-a85f-42010a9c0002&amp;#x27;)) or ((&amp;#x60;test&amp;#x60;.&amp;#x60;mobile_stat_device&amp;#x60;.&amp;#x60;deviceUuidHash&amp;#x60; = &amp;lt;cache&amp;gt;(crc32(&amp;#x27;36fffd73-519b-11eb-a85f-42010a9c0002&amp;#x27;))) and (&amp;#x60;test&amp;#x60;.&amp;#x60;mobile_stat_device&amp;#x60;.&amp;#x60;deviceUuid&amp;#x60; = &amp;#x27;36fffd73-519b-11eb-a85f-42010a9c0002&amp;#x27;)))&amp;quot;
    }
  }
}&lt;/pre&gt;
  &lt;p&gt;Обратите внимание, насколько упал &lt;code&gt;query_cost&lt;/code&gt; и насколько меньше записей выбирается.&lt;/p&gt;
  &lt;p&gt;Вывода два:&lt;/p&gt;
  &lt;ol&gt;
    &lt;li&gt;Быть осторожнее с вычислительными значениями в запросах, если эти значения используются в where.&lt;/li&gt;
    &lt;li&gt;Нагружать БД данными и потом уже проверять насколько корректно отрабатывают запросы. &lt;/li&gt;
  &lt;/ol&gt;
  &lt;tt-tags&gt;
    &lt;tt-tag name=&quot;mysql&quot;&gt;#mysql&lt;/tt-tag&gt;
    &lt;tt-tag name=&quot;sql&quot;&gt;#sql&lt;/tt-tag&gt;
    &lt;tt-tag name=&quot;оптимизация_запросов&quot;&gt;#оптимизация_запросов&lt;/tt-tag&gt;
  &lt;/tt-tags&gt;

</content></entry><entry><id>devguru:cloudflare-workers</id><link rel="alternate" type="text/html" href="https://blog.devgu.ru/cloudflare-workers?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=devguru"></link><title>Cloudflare workers - хорошее решение для быстрого старта.</title><published>2021-01-04T08:37:36.218Z</published><updated>2021-01-04T08:37:36.218Z</updated><tt:hashtag>javascript</tt:hashtag><tt:hashtag>cloudflare</tt:hashtag><tt:hashtag>cloudflare_workers</tt:hashtag><summary type="html">Вы наверняка знаете, что такое cloudflare, но знаете ли вы, что у них есть очень клёвая услуга для построения бессерверных (serverless) приложений? Воркеры! </summary><content type="html">
  &lt;p&gt;Вы наверняка знаете, что такое &lt;a href=&quot;https://www.cloudflare.com/&quot; target=&quot;_blank&quot;&gt;cloudflare&lt;/a&gt;, но знаете ли вы, что у них есть очень клёвая услуга для построения бессерверных (serverless) приложений? &lt;a href=&quot;https://developers.cloudflare.com/workers/&quot; target=&quot;_blank&quot;&gt;Воркеры!&lt;/a&gt; &lt;/p&gt;
  &lt;p&gt;Услуга нацелена прежде всего на разработчиков мобильных приложений, чтобы без всякого геморроя поднимать бэкенды для своих аппликух. Кроме обработчиков запросов имеется KV-хранилище и даже воркеры, которые работают по расписанию. Отладчик, песочница - всё в наличии. Что еще надо, чтобы поднять простенький бэкэнд?&lt;/p&gt;
  &lt;p&gt;А если учесть, что воркер может запускаться на тысячах машин распределенных по миру, выбирая наиболее близкую для клиента локацию, решение мне видится идеальным для быстрого старта. &lt;/p&gt;
  &lt;p&gt;И самое главное - вся эта красота бесплатна, если запросов меньше, чем 100 000 в день.&lt;/p&gt;
  &lt;p&gt;Однако, данную технологию могут использовать не только фронтендеры, но и все желающие, подключив фантазию. Например, можно &lt;a href=&quot;https://medium.com/@TarasPyoneer/how-to-set-up-a-custom-domain-for-your-homepage-in-notion-53fa3d54f848&quot; target=&quot;_blank&quot;&gt;прикрутить собственный домен для notion&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Я же на коленке написал воркер, который отдаёт &lt;a href=&quot;https://blog.devgu.ru/tool-github-gist-to-irame-converter&quot; target=&quot;_blank&quot;&gt;код конвертера&lt;/a&gt; и добавил его в статью teletype через iframe. Вот что получилось:&lt;/p&gt;
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;iframe src=&quot;data:text/html;charset=utf-8, &lt;head&gt;&lt;base target=&amp;#x27;_blank&amp;#x27; /&gt;&lt;/head&gt; &lt;body&gt;&lt;script src=&amp;#x27;https://gist.github.com/bojik/24e03ea511edd4c41b02a02c2d940454.js&amp;#x27;&gt;&lt;/script&gt; &lt;/body&gt;&quot;&gt;&lt;/iframe&gt;
    &lt;figcaption&gt;Воркер клаудфлеер для оттдачи кода конвертера&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;tt-tags&gt;
    &lt;tt-tag name=&quot;javascript&quot;&gt;#javascript&lt;/tt-tag&gt;
    &lt;tt-tag name=&quot;cloudflare&quot;&gt;#cloudflare&lt;/tt-tag&gt;
    &lt;tt-tag name=&quot;cloudflare_workers&quot;&gt;#cloudflare_workers&lt;/tt-tag&gt;
  &lt;/tt-tags&gt;

</content></entry><entry><id>devguru:tool-github-gist-to-irame-converter</id><link rel="alternate" type="text/html" href="https://blog.devgu.ru/tool-github-gist-to-irame-converter?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=devguru"></link><title>Конвертер из GitHub Gist в iframe представление</title><published>2020-12-30T08:07:36.677Z</published><updated>2020-12-30T08:29:17.681Z</updated><category term="instrumenty" label="Инструменты"></category><tt:hashtag>github_gist</tt:hashtag><tt:hashtag>github</tt:hashtag><tt:hashtag>teletype_in</tt:hashtag><tt:hashtag>tools</tt:hashtag><summary type="html">Помучился с гистами и телетайпом и решил упростить себе, а заодно и еще кому-то, жизнь - сделать на коленке конвертер.</summary><content type="html">
  &lt;p&gt;Помучился с гистами и телетайпом и решил упростить себе, а заодно и еще кому-то, жизнь - сделать на коленке конвертер.&lt;/p&gt;
  &lt;p&gt;Сформированный код необходимо вставить в блок iframe телетайпа и всё должно работать ;-)&lt;/p&gt;
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;iframe src=&quot;https://soft-sound-4002.devguru.workers.dev/&quot;&gt;&lt;/iframe&gt;
    &lt;figcaption&gt;Converter embed code of github gist to iframe&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;tt-tags&gt;
    &lt;tt-tag name=&quot;github_gist&quot;&gt;#github_gist&lt;/tt-tag&gt;
    &lt;tt-tag name=&quot;github&quot;&gt;#github&lt;/tt-tag&gt;
    &lt;tt-tag name=&quot;teletype_in&quot;&gt;#teletype_in&lt;/tt-tag&gt;
    &lt;tt-tag name=&quot;tools&quot;&gt;#tools&lt;/tt-tag&gt;
  &lt;/tt-tags&gt;

</content></entry><entry><id>devguru:github-gist-teletype-in</id><link rel="alternate" type="text/html" href="https://blog.devgu.ru/github-gist-teletype-in?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=devguru"></link><title>Как разместить github gist в постах на платформе Teletype</title><published>2020-12-22T08:41:13.597Z</published><updated>2020-12-30T08:28:36.442Z</updated><tt:hashtag>github</tt:hashtag><tt:hashtag>github_gist</tt:hashtag><tt:hashtag>teletype_in</tt:hashtag><tt:hashtag>блоггерское</tt:hashtag><summary type="html">&lt;img src=&quot;https://teletype.in/files/79/15/7915fea9-1228-4eb8-90c0-904717b9383d.jpeg&quot;&gt;Открыть контекст текстового блока, выбрать iframe.</summary><content type="html">
  &lt;p&gt;Открыть контекст текстового блока, выбрать iframe.&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/79/15/7915fea9-1228-4eb8-90c0-904717b9383d.jpeg&quot; width=&quot;234&quot; /&gt;
    &lt;figcaption&gt;В контекстном меню выбать iframe&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;Поправить следующий код, указав правильные размеры и embed код на нужный гист. &lt;strong&gt;Не забыть заменить в коде гиста двойные кавычки на одинарные.&lt;/strong&gt; &lt;/p&gt;
  &lt;p&gt;&lt;strong&gt;UPD:&lt;/strong&gt; Если руками делать не хочется, милости прошу, &lt;a href=&quot;https://blog.devgu.ru/tool-github-gist-to-irame-converter&quot; target=&quot;_blank&quot;&gt;автоматическое средство&lt;/a&gt; &lt;/p&gt;
  &lt;p&gt;Разместить код в открывшемся окошке.&lt;/p&gt;
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;iframe src=&quot;data:text/html;charset=utf-8, &lt;head&gt;&lt;base target=&amp;#x27;_blank&amp;#x27; /&gt;&lt;/head&gt; &lt;body&gt;&lt;script src=&amp;#x27;https://gist.github.com/Albert-W/e37d1c4fa30c430c37d7b1b1fe9b60d8.js&amp;#x27;&gt;&lt;/script&gt; &lt;/body&gt;&quot;&gt;&lt;/iframe&gt;
  &lt;/figure&gt;
  &lt;tt-tags&gt;
    &lt;tt-tag name=&quot;github&quot;&gt;#github&lt;/tt-tag&gt;
    &lt;tt-tag name=&quot;github_gist&quot;&gt;#github_gist&lt;/tt-tag&gt;
    &lt;tt-tag name=&quot;teletype_in&quot;&gt;#teletype_in&lt;/tt-tag&gt;
    &lt;tt-tag name=&quot;блоггерское&quot;&gt;#блоггерское&lt;/tt-tag&gt;
  &lt;/tt-tags&gt;

</content></entry></feed>