Оптимизация производительности MySQL (6) -- есть и существует

MySQL

Что лучше, есть или есть?

sql-скрипт:

/*建库*/
create database testdb6;
use testdb6;
/* 用户表 */
drop table if exists users;
create table users(
	id int primary key auto_increment,
	name varchar(20)
);
insert into users(name) values ('A');
insert into users(name) values ('B');
insert into users(name) values ('C');
insert into users(name) values ('D');
insert into users(name) values ('E');
insert into users(name) values ('F');
insert into users(name) values ('G');
insert into users(name) values ('H');
insert into users(name) values ('I');
insert into users(name) values ('J');

/* 订单表 */
drop table if exists orders;
create table orders(
	id int primary key auto_increment,/*订单id*/
	order_no varchar(20) not null,/*订单编号*/
	title varchar(20) not null,/*订单标题*/
	goods_num int not null,/*订单数量*/
	money decimal(7,4) not null,/*订单金额*/
	user_id int not null    /*订单所属用户id*/
)engine=myisam default charset=utf8 ;

delimiter ?
drop procedure batch_orders ?

/* 存储过程 */
create procedure batch_orders(in max int)
begin
declare start int default 0;
declare i int default 0;
set autocommit = 0;  
while i < max do
   set i = i + 1;
   insert into orders(order_no,title,goods_num,money,user_id) 
   values (concat('NCS-',floor(1 + rand()*1000000000000 )),concat('订单title-',i),i%50,(100.0000+(i%50)),i%10);
 &emsp; end while;
commit;
end ?
delimiter ;

/*插入1000万条订单数据*/
call batch_orders(10000000);     /*插入数据的过程根据机器的性能 花费的时间不同,有的可能3分钟,有的可能10分钟*/

В приведенном выше sql есть user_id в таблице заказов (заказы) и есть таблица пользователей (пользователи), поэтому мы используем user_id в таблице заказов и идентификатор в таблице пользователей, чтобы существовать.

результат

1. где следует небольшая таблица

(1) выберите count(1) из заказов o, где o.user_id in(выберите u.id из пользователей u);

img

(2) выберите количество (1) из заказов o, где они существуют (выберите 1 из пользователей u, где u.id = o.user_id);

img

2. где следует большая таблица

(1) выберите count(1) из пользователей u, где u.id in (выберите o.user_id из заказов o);

img

(2) выберите количество (1) из пользователей u, где они существуют (выберите 1 из заказов o, где o.user_id = u.id);

img

анализировать

Мы используем следующие два утверждения для анализа:

select count(1) from orders o where o.user_id in(select u.id from users u);
select count(1) from orders o where exists (select 1 from users u where u.id = o.user_id);

1.in: сначала запросить таблицу пользователей, а затем отфильтровать заказы, то есть сначала выполнить подзапрос, а затем пройти основной запрос после получения результата.Обход основного запроса основан на равенстве user_id и идентификатор.

То есть запрос к таблице пользователей эквивалентен внешнему циклу, а основной запрос — это внешний цикл.

Резюме: сначала выполняется подзапрос, т.е.in()содержащееся заявление. После того, как подзапрос запрашивает данные, предыдущий запрос делится на n обычных запросов (n представляет собой количество строк данных, возвращенных в подзапросе).

2.exists: основной запрос — это внутренний цикл, сначала запрашивайте заказы, запрашивайте заказы — это внешний цикл, а затем оценивайте, равны ли order_id и id в таблице пользователей, и сохраняйте данные только в том случае, если они равны , и запрос таблицы пользователей - это внутренний цикл

Упомянутые здесь внешний цикл и внутренний цикл — это то, что мы называем вложенными циклами, а вложенные циклы должны следовать принципу «маленький снаружи и большой внутри», что похоже на копирование множества маленьких файлов и копирование нескольких больших файлов.

Резюме: если подзапрос находит данные, он возвращает логическое значение true, если нет, возвращает логическое значение false. Возврат логического значения true сохранит часть данных, в противном случае она будет отброшена. Другими словами, существующий запрос должен выполнять подзапрос после запроса части данных.

в заключении

Маленькие столы управляют большими столами.

in подходит для случая, когда внешний вид большой, а внутренний маленький, а существует подходит для случая, когда внешний вид маленький, а внутренний большой.


Добро пожаловать, чтобы обратить внимание на мою официальную учетную запись и получать последние статьи как можно скорее ~ Выполните поиск в официальной учетной записи: Code Cafe или отсканируйте QR-код ниже:

img