当前位置:网站首页>[2022 dark horse programmer] SQL optimization
[2022 dark horse programmer] SQL optimization
2022-06-25 06:46:00 【Xiao Qi rrrrrrr】
【 Black horse programmer 】SQL Optimize notes
List of articles
Insert data optimization
If we need to insert multiple records into the database table at one time , It can be optimized from the following three aspects .
- Bulk insert data
- Manually control transactions
- Insert primary key in order , Performance is better than out of order insertion
Mass insert data
If you need to insert a large amount of data at one time ( such as : Millions of records ), Use insert Statement insertion performance is low , You can use MySQL Database provides load Instructions Insert . The operation is as follows :

First, import the prepared data into root Under the table of contents , Create a new one itheima The database of

When the client connects to the server , Add parameters -–local-infile
mysql –-local-infile -u root -Set global parameters local_infile by 1, Turn on the switch to import data from the local load file
set global local_infile = 1;You can see that local_infile Have been to 1
![[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-yxjLlJ4I-1655971250612)(【 Black horse programmer 】SQL Optimize notes .assets/image-20220622153117106.png)]](/img/ee/d3e3d720165882c6c3a30b326a1ee6.png)
Create a table
CREATE TABLE `tb_user` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `username` VARCHAR(50) NOT NULL, `password` VARCHAR(50) NOT NULL, `name` VARCHAR(20) NOT NULL, `birthday` DATE DEFAULT NULL, `sex` CHAR(1) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `unique_user_username` (`username`) ) ENGINE=INNODB DEFAULT CHARSET=utf8 ;perform load The instruction will prepare the data , Load into table structure
load data local infile '/root/sql1.log' into table tb_user fields terminated by ',' lines terminated by '\n' ;You can see the insertion time
![[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-iibKN3YQ-1655971250613)(【 Black horse programmer 】SQL Optimize notes .assets/image-20220622153534003.png)]](/img/94/645e7626eac270608e3bd3f1945cb9.png)
stay load when , The performance of primary key sequential insertion is better than that of out of order insertion
summary
Bulk insert data
Insert into tb_test values(1,'Tom'),(2,'Cat'),(3,'Jerry');Manually control transactions
start transaction; insert into tb_test values(1,'Tom'),(2,'Cat'),(3,'Jerry'); insert into tb_test values(4,'Tom'),(5,'Cat'),(6,'Jerry'); insert into tb_test values(7,'Tom'),(8,'Cat'),(9,'Jerry'); commit;Insert primary key in order , Performance is better than out of order insertion
The primary key is inserted out of order : 8 1 9 21 88 2 4 15 89 5 7 3 Insert primary key in order : 1 2 3 4 5 7 8 9 15 21 88 89Large scale data , have access to load
Primary key optimization
How data is organized
stay InnoDB In the storage engine , Table data is organized and stored according to the primary key sequence , The tables in this way are called Index organization table (index organized table IOT).
![[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-rq0hNms8-1655971250614)(【 Black horse programmer 】SQL Optimize notes .assets/image-20220623104439108.png)]](/img/87/122468fd977564502db99eb6a60b1a.png)
Row data , Are stored on the leaf node of the clustered index
![[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-58dfpq0o-1655971250615)(【 Black horse programmer 】SQL Optimize notes .assets/image-20220623104500387.png)]](/img/9b/62025ef45f68efdd44a9335f0910f2.png)
stay InnoDB In the engine , Data lines are recorded in logical structures page On page , And the size of each page is fixed , Default 16K. That means , The rows stored in a page are also limited , If the inserted data row row The size of is larger than the maximum storage capacity of the page , Then it will be stored in the next page , Pages are connected by pointers .
Page splitting
The page can be empty , You can fill half , You can also fill in 100%. Each page contains 2-N Row data ( If a row of data is too large , Line overflow ), Arrange according to the primary key .
A. Primary key sequence insertion effect
①. Request page from disk , Primary key sequential interpolation
![[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-XB93eqfu-1655971250616)(【 Black horse programmer 】SQL Optimize notes .assets/image-20220623104940228.png)]](/img/5d/2053e0c87ed82fdfa8a91234d333ac.png)
②. The first page is not full , Continue to insert... On the first page
![[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-HWpdrE4r-1655971250616)(【 Black horse programmer 】SQL Optimize notes .assets/image-20220623104954355.png)]](/img/09/13fffdd557cd61a1711fb302b27ed7.png)
③. When the first one is full , Write the second page , Pages are connected by pointers
![[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-bEqcxfrY-1655971250617)(【 Black horse programmer 】SQL Optimize notes .assets/image-20220623105007278.png)]](/img/dd/84970e7abeb349fec858ec8187bd99.png)
④. When the second page is full , Then write to the third page
B. The primary key is inserted out of order
①. Join in 1#,2# The pages are full , The data shown in the figure is stored
![[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-E8gkCHhK-1655971250617)(【 Black horse programmer 】SQL Optimize notes .assets/image-20220623105034944.png)]](/img/19/a34727f6b4abeb72fdede3cfc59d95.png)
②. Insert again at this time id by 50 The record of , Let's see what happens
![[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-9Si1KOXK-1655971250618)(【 Black horse programmer 】SQL Optimize notes .assets/image-20220623105049141.png)]](/img/eb/84707ff6ffb82e847fd3fcac0de638.png)
Will not open a page again , Insert into new page ,** because , The leaf nodes of the index structure are in order . In order , It should be stored in 47 after .** however 47 Where 1# page , It's full , Can't store 50 The corresponding data . Then a new page will be opened 3#. But it will not directly 50 Deposit in 3# page , It's about putting 1# The data in the second half of the page , Move to 3# page , And then in 3# page , Insert 50.
![[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-AhEGATpy-1655971250619)(【 Black horse programmer 】SQL Optimize notes .assets/image-20220623105213076.png)]](/img/bc/f97632010f46a471d776d8f33b2bc1.png)
mobile data , And insert id by 50 After the data of , So at this time , The data order between these three pages is problematic . 1# Next page of , Should be 3#, 3# The next page is 2#. therefore , here , Need to reset the linked list pointer .
![[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-r9kn1CcI-1655971250619)(【 Black horse programmer 】SQL Optimize notes .assets/image-20220623105244360.png)]](/img/ff/6817704e7ff94f20482bc90e48e3ab.png)
The above phenomenon , be called “ Page splitting ”, It is a performance consuming operation .
Page merge
![[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-iMX1bdrx-1655971250619)(【 Black horse programmer 】SQL Optimize notes .assets/image-20220623105308885.png)]](/img/0a/c3b420b4cfc760fffae4e4d686eb88.png)
When we delete existing data , The specific effects are as follows : When deleting a row of records , In fact, the record has not been physically deleted , Just the record is marked (flaged) To delete And its space becomes allowed to be used by other record declarations .
![[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-R7VU1IXI-1655971250620)(【 Black horse programmer 】SQL Optimize notes .assets/image-20220623105333061.png)]](/img/f8/227b08d12618890e101b85ef3b327c.png)
When we continue to delete 2# Data record of , When the record deleted in the page reaches MERGE_THRESHOLD( The default is... Of the page 50%),InnoDB Will start looking for the closest page ( front Or after ) See if you can merge two pages to optimize space usage .
![[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-2OHyn3i7-1655971250620)(【 Black horse programmer 】SQL Optimize notes .assets/image-20220623105359931.png)]](/img/1a/e370b6de88da5792b74f3314b67343.png)
Delete data , And merge the pages , Insert new data again 21, And just insert 3# page
![[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-s9PWUrJV-1655971250621)(【 Black horse programmer 】SQL Optimize notes .assets/image-20220623105420187.png)]](/img/d8/ca3c3e7f6e77ba88f869009ad6a2f3.png)
The phenomenon of merging pages that occurs in this , It's called “ Page merge ”.
Knowledge tips : MERGE_THRESHOLD: The threshold for merging pages , You can set it yourself , Specify... When creating a table or index .
Index design principles
- Meet business needs , Try to reduce the length of the primary key .
- When inserting data , Try to insert in order , Choose to use AUTO_INCREMENT Since the primary key .
- Try not to use UUID Make primary keys or other natural primary keys , Such as ID card No .
- During business operation , Avoid modifying the primary key .
order by Optimize
MySQL Sort , There are two ways :
- Using filesort : Through table index or full table scan , Read the data lines that meet the conditions , Then in the sort buffer sort buffer Complete the sorting operation in , All sorts that do not return sorting results directly through index are called FileSort Sort .
- Using index : Through the sequential scan of the ordered index, the ordered data can be returned directly , This is the case using index, No need for extra sorting , High operating efficiency .
For the above two sorting methods ,Using index High performance , and Using filesort Low performance , When we optimize sorting operations , Try to optimize for Using index.
test
Put the previous test , by tb_user Some indexes established by the table are deleted directly
drop index idx_user_phone on tb_user; drop index idx_user_phone_name on tb_user; drop index idx_user_name on tb_user;![ [ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-VZLYgT5P-1655971250621)(【 Black horse programmer 】SQL Optimize notes .assets/image-20220623105811923.png)]](/img/6c/a4ced3d7c89ad9db4db66f0eba4651.png)
Perform sorting SQL
explain select id,age,phone from tb_user order by age ;![[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-PVLWkDmn-1655971250622)(【 Black horse programmer 】SQL Optimize notes .assets/image-20220623134615673.png)]](/img/43/a0fecf9264ca995f6ff0bf4d339e3e.png)
because age, phone There's no index , So when sorting again at this time , appear Using filesort, Low sorting performance .Index
create index idx_user_age_phone_aa on tb_user(age,phone);After index creation , according to age, phone Sort in ascending order
explain select id,age,phone from tb_user order by age![[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-VLMtG5ng-1655971250622)(【 Black horse programmer 】SQL Optimize notes .assets/image-20220623134800233.png)]](/img/c0/4d6bd320b3e835ed41d1f041f25ca6.png)
explain select id,age,phone from tb_user order by age , phone;![[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-qhOX51MB-1655971250622)(【 Black horse programmer 】SQL Optimize notes .assets/image-20220623134827338.png)]](/img/30/200522e56b144b62295d91b068a9de.png)
After indexing , Sort again , From the original Using filesort, Change into Using index, The performance is relatively high .
After index creation , according to age, phone Sort in descending order
![[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-3SVjNq9z-1655971250623)(【 Black horse programmer 】SQL Optimize notes .assets/image-20220623134925141.png)]](https://img-blog.csdnimg.cn/6ecd03b5a28e4984ba12fd63123f07ae.png)
according to phone,age Sort in ascending order ,phone before ,age After .
![[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-B2mZrR2c-1655971250623)(【 Black horse programmer 】SQL Optimize notes .assets/image-20220623135020277.png)]](/img/a2/bf5618052b6dd90dd1e7074424f9a2.png)
Sorting time , Also need to satisfy the leftmost prefix rule , Otherwise, there will be filesort. Because when creating an index , age Is the first Field ,phone It's the second field , therefore Sorting time , We should follow this order , Otherwise, it will appear Using filesort.according to age, phone In descending order, in ascending order , A descending order
explain select id,age,phone from tb_user order by age asc , phone desc ;![[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-GuE4grbe-1655971250624)(【 Black horse programmer 】SQL Optimize notes .assets/image-20220623135109035.png)]](/img/68/92ee1ff47428e17aca0feb0e33382e.png)
Because when you create an index , If the order is not specified , By default, they are sorted in ascending order , And when you query , An ascending order , A descending order , here Will appear Using filesort.
In order to solve the above problems , We can create an index , In this joint index age Ascending sort ,phone Reverse sort .create index idx_user_age_phone_ad on tb_user(age asc ,phone desc);![[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-p6hylM1m-1655971250624)(【 Black horse programmer 】SQL Optimize notes .assets/image-20220623153012259.png)]](/img/4d/a6bb2d4f2cfdff77278ba840300695.png)
Then perform the following again SQL
explain select id,age,phone from tb_user order by age asc , phone desc ;Support mysql8.0 edition
![[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-cRgqeWlE-1655971250625)(【 Black horse programmer 】SQL Optimize notes .assets/image-20220623153046480.png)]](/img/71/adce77e39ab0772b296b14fdbc833c.png)
order by Optimize the rules
- Establish the appropriate index according to the sorting field , When sorting multiple fields , Also follow the leftmost prefix rule .
- Try to use overlay index .
- Multi field sorting , One ascending, one descending , At this time, you need to pay attention to the rules when creating the federated index (ASC/DESC).
- If inevitable filesort, When sorting large amounts of data , You can appropriately increase the size of the sorting buffer sort_buffer_size( Default 256k).
group by Optimize
Execute without an index group by
Delete all indexes
drop index idx_user_pro_age_sta on tb_user;
drop index idx_email_5 on tb_user;
drop index idx_user_age_phone_aa on tb_user;
drop index idx_user_age_phone_ad on tb_user;
Execute query statement
explain select profession , count(*) from tb_user group by profession ;
![[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-LFkVr3PB-1655971250625)(【 Black horse programmer 】SQL Optimize notes .assets/image-20220623153422541.png)]](/img/5a/65cfc484b0694f2270a5a7a2aa061b.png)
then , We are aiming at profession , age, status Create a federated index .
create index idx_user_pro_age_sta on tb_user(profession , age , status):
And then execute :
explain select profession , count(*) from tb_user group by profession
![[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-Vp1wV7gf-1655971250626)(【 Black horse programmer 】SQL Optimize notes .assets/image-20220623153525274.png)]](/img/69/4b1bd105600c86a1f411cace1e889e.png)
![[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-jYOBVo3u-1655971250626)(【 Black horse programmer 】SQL Optimize notes .assets/image-20220623153912984.png)]](/img/02/3c83ede6ad2cbdfbd232924643473a.png)
Only age Grouping
explain select age, count(*) from tb_user group by age;
![[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-Wl98aubn-1655971250627)(【 Black horse programmer 】SQL Optimize notes .assets/image-20220623153813498.png)]](/img/04/3161a012160484bc5926b9d2344f0e.png)
We found that , If only based on age grouping , Will appear Using temporary ; And if it is according to profession,age Two fields are grouped at the same time , Will not appear Using temporary. The reason is that for grouping operations , In the union index , It also conforms to the leftmost prefix rule .
Grouping optimization rules
therefore , In grouping operations , We need to optimize through the following two points , To improve performance :
- During grouping operation , Efficiency can be improved by indexing .
- When grouping , The use of index also satisfies the leftmost prefix rule .
limit Optimize
When the amount of data is large , If carried out limit Paging query , In the query , The later , The lower the efficiency of paging query .
limit Comparison of paging query time
![[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-IRa0ao5q-1655971250627)(【 Black horse programmer 】SQL Optimize notes .assets/image-20220623155037955.png)]](/img/c8/26bfdd82d85c0c41e75a5a58a1951e.png)
![[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-C1dw4FSk-1655971250628)(【 Black horse programmer 】SQL Optimize notes .assets/image-20220623155121895.png)]](/img/34/63afd768eeb98e3179d8053233bd4a.png)
![[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-TeeBkpDR-1655971250628)(【 Black horse programmer 】SQL Optimize notes .assets/image-20220623155135439.png)]](/img/f0/3a7a4d08e5e7f1665d1f53d5579462.png)
Through the test, we will see , The later , The lower the efficiency of paging query , That's the problem with paging queries .
Optimization idea : General paging query , Better performance can be achieved by creating indexes , You can add subqueries by overriding the index Query form is optimized .
Search without index
select * from tb_user limit 999000,10;
![[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-gfa8WfmZ-1655971250628)(【 Black horse programmer 】SQL Optimize notes .assets/image-20220623155357708.png)]](/img/5c/3daec19cabd527f2a75ca143a2a9e3.png)
Use the index to search
mysql> select id from tb_user order by id limit 999000,10;

Use overlay query + Socket sub query to search
explain select * from tb_user t , (select id from tb_user order by id limit 999000,10) a where t.id = a.id;
![[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-EjWg8C9w-1655971250629)(【 Black horse programmer 】SQL Optimize notes .assets/image-20220623155308775.png)]](/img/12/df0c54f796d9a6daea5ae69d4d25ae.png)


count Optimize
select count(*) from tb_user
If you want to improve significantly InnoDB Tabular count efficiency , The main optimization ideas : Count yourself ( With the aid of redis Such a number According to the database , But if it's conditional count It's more troublesome again ).
count usage
count() It's an aggregate function , For the returned result set , Judge line by line , If count The argument to the function is not NULL, Add... To the cumulative value 1, Otherwise, we will not add , Finally return the cumulative value .
usage :count(*)、count( Primary key )、count( Field )、count( Numbers )
![[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-9d30zHAC-1655971250631)(【 Black horse programmer 】SQL Optimize notes .assets/image-20220623155756637.png)]](/img/68/f209848e4de4131c7c5492af65b1d1.png)
In order of efficiency ,count( Field ) < count( Primary key id) < count(1) ≈ count(), So try to Amount of use count().
update Optimize
update course set name = 'javaEE' where id = 1 ;
When we delete SQL When the sentence is , Will lock id by 1 Data in this row , Then after the transaction is committed , Row lock release .
But when we are performing the following SQL when .
update course set name = 'SpringBoot' where name = 'PHP' ;
When we start multiple transactions , In performing the above SQL when , We found that row locks were upgraded to table locks . This leads to the update Statement performance Greatly reduced . because name Field has no index .
InnoDB The row lock of is the lock added for the index , It's not a lock on records , And the index cannot be invalidated , Otherwise, it will be upgraded from row lock to table lock .
nt( Primary key id) < count(1) ≈ count(), So try to Amount of use count().
update Optimize
update course set name = 'javaEE' where id = 1 ;
When we delete SQL When the sentence is , Will lock id by 1 Data in this row , Then after the transaction is committed , Row lock release .
But when we are performing the following SQL when .
update course set name = 'SpringBoot' where name = 'PHP' ;
When we start multiple transactions , In performing the above SQL when , We found that row locks were upgraded to table locks . This leads to the update Statement performance Greatly reduced . because name Field has no index .
InnoDB The row lock of is the lock added for the index , It's not a lock on records , And the index cannot be invalidated , Otherwise, it will be upgraded from row lock to table lock .
So go ahead update When , Try to use the index to judge .
边栏推荐
- [no title] dream notes 2022-02-20
- Leetcode 2163. Minimum difference of sum after element deletion
- Capable people never complain about the environment!
- fastadmin 联级清空数据
- Cs4344/ht5010 stereo d/a digital to analog converter
- Microsoft issued a document to celebrate Net 20th anniversary!
- [learn FPGA programming from scratch -43]: vision chapter - technology evolution of chip design in the post Moore era -2- evolution direction
- What is VLAN
- Torchserve pit avoidance Guide
- Ctfhub web information disclosure directory traversal
猜你喜欢

The process of making wooden barrels with 3DMAX software: a three-step process

Ht8513 single lithium battery power supply with built-in Dynamic Synchronous Boost 5W mono audio power amplifier IC solution

R & D thinking 07 - embedded intelligent product safety certification required

Uncaught TypeError: Cannot read properties of undefined (reading ‘prototype‘)
![[200 opencv routines of youcans] 104 Motion blur degradation model](/img/a9/8841ffc8bd3c486bc4011a1a84ff45.jpg)
[200 opencv routines of youcans] 104 Motion blur degradation model

ACWING2013. 三条线

Navicat prevent new query from being deleted by mistake

Microsoft issued a document to celebrate Net 20th anniversary!

Non-contact infrared temperature measurement system for human body based on single chip microcomputer

Cs8683 (120W mono class D power amplifier IC)
随机推荐
Learn the first routine of FPGA
Understand ZBrush carving software and game modeling analysis
Ctfhub web - divulgation d'informations - traversée du Répertoire
Microsoft issued a document to celebrate Net 20th anniversary!
Grouped uitableview has 20px of extra padding at the bottom
Missing libgmp-10 dll - libgmp-10. dll is missing
Streaming a large file using PHP
Cannot activate inspection type when SAP retail uses transaction code mm41 to create commodity master data?
Atomic alpha development board -- SD card and EMMC burning tool
Error reported during vivado simulation common 17-39
How to configure log4j to only keep log files for the last seven days?
keil debug查看变量提示not in scope
Your local changes to the following files would be overwritten by merge: . vs/slnx. sqlite
Derivation of COS (a-b) =cosa*cosb+sina*sinb
Cs8683 (120W mono class D power amplifier IC)
ASP. Net core - Safety of asynclocal in asp NET Core
Bcrypt password encryption kalrry
How to realize the stable output of 3.3v/3.6v (1.2-5v) voltage of lithium battery by using the voltage rise and fall chip cs5517
cos(a-b)=cosa*cosb+sina*sinb的推导过程
Uncaught TypeError: Cannot read properties of undefined (reading ‘prototype‘)