当前位置: 首页 > 编程日记 > 正文

MySQL索引优化实战

联合索引第一个字段用范围不会走索引 type = all

EXPLAIN SELECT * FROM employees 
WHERE name > 'LiLei' AND age = 22 AND position ='manager';

因为MySQL有自己的优化机制,当索引中第一个字段是 大于 小于 那么MySQL就会认为会扫描出很多条数据 并且是二级索引可能还要回表,那么多数据需要回表还不如不走当前使用索引直接走主键索引全表扫描

强制索引

EXPLAIN SELECT * FROM employees 
force index(idx_name_age_position) 
WHERE name > 'LiLei' AND age = 22 AND position ='manager';

因为where中第一个是name 原本应该走索引但是因为 使用的是范围查询 MySQL认为索引第一个字段就是范围查询 计算得出成本比全表扫描成本还大 就会走全表扫描

但是如果MySQL计算成本错误,走索引还是比较快的 那么我们可以强制让MySQL走索引。

使用 force index(索引名称) 就会强制走索引

MySQL走不走索引也会跟 name > 'LiLei' 得出的数据多少有关 如果很多 但是后面还有字段 age作为条件 这时候就会全表扫描,后面age = 22 是肯定不能走索引了,因为前边 使用 name > 'LiLei' 已经让age无序了

使用索引优化

select 后面不要跟 * ,尽量使用二级索引中索引字段 这样不需要回表

in和or在表数据量比较大的情况会走索引,在表记录不多的情况下会选择全表扫描

因为 数据比较少的话 MySQL认为走in 还要回表 并且数据本身就少 直接全表查询也比较容易就那么点数据 还不需要回表 并且 in 还可能包好全表数据 所以MySQL在数据少的情况下会全表

如果数据量大,那么走索引还是比较快的,因为那么多数据 走 in 索引比全表扫描成本低

like 'KK%' 一般情况都会走索引

假设表中有联合索引:index_test(name,age,gend);

where name like 'KK%' and age = 10 and gend = '男';

like 'kk%'走索引是因为MySQL中都是排好序的 通过 'kk%'其实就是相当于是一个 范围查询 的意思,但是MySQL会认为 模糊查询得到的数据量会比 > 、< 这种得到的数据量小 所以会走索引但是第一个字段是 <、>不走索引

索引下推(ICP)

MySQL5.6版本之前 使用的是 二级索引name找到的所有主键id 去回表主键索引

MySQL5.6版本之后使用的是 二级索引name匹配到符合的值以后再根据后面的 age 和 gend再过滤拿到最终的主键id去主键索引中回表 这样的好处就是回表的时候主键id会减少。

like 'kk%' 会走索引下推

<、>不走索引下推 因为MySQL认为 like 'kk%' 已经过滤掉很多数据了 所以走索引下推,而 <、>认为过滤以后还有很多数据 这样还不如全表查询还需要回表 所以不走索引并且不走索引下推

范围查询不会走索引下推,因为MySQL认为范围查询数据量会比较多,所以不走索引

查看MySQL 成本计算方式

set session optimizer_trace="enabled=on",end_markers_in_json=on; ‐‐开启trace
select * from employees where name > 'a' order by position;
SELECT * FROM information_schema.OPTIMIZER_TRACE;

第一句第三句固定写死 第二句是要执行的sql

{
 "steps": [
 {
 "join_preparation": { ‐‐第一阶段:SQL准备阶段,格式化sql
 "select#": 1,
 "steps": [
 {
 "expanded_query": "/* select#1 */ select `employees`.`id` AS `id`,`employees`.`name` AS `name`,`empl
oyees`.`age` AS `age`,`employees`.`position` AS `position`,`employees`.`hire_time` AS `hire_time` from
`employees` where (`employees`.`name` > 'a') order by `employees`.`position`"
 }
        ] /* steps */
        } /* join_preparation */
        },
        {
        "join_optimization": { ‐‐第二阶段:SQL优化阶段
        "select#": 1,
        "steps": [
        {
        "condition_processing": { ‐‐条件处理
        "condition": "WHERE",
        "original_condition": "(`employees`.`name` > 'a')",
        "steps": [
        {
        "transformation": "equality_propagation",
        "resulting_condition": "(`employees`.`name` > 'a')"
        },
        {
        "transformation": "constant_propagation",
        "resulting_condition": "(`employees`.`name` > 'a')"
        },
        {
        "transformation": "trivial_condition_removal",
        "resulting_condition": "(`employees`.`name` > 'a')"
        }
        ] /* steps */
        } /* condition_processing */
        },
        {
        "substitute_generated_columns": {
        } /* substitute_generated_columns */
        },
        {
        "table_dependencies": [ ‐‐表依赖详情
        {
        "table": "`employees`",
        "row_may_be_null": false,
        "map_bit": 0,
        "depends_on_map_bits": [
        ] /* depends_on_map_bits */
        }
        ] /* table_dependencies */
        },
        {
        "ref_optimizer_key_uses": [
        ] /* ref_optimizer_key_uses */
        },
        {
        "rows_estimation": [ ‐‐预估表的访问成本
        {
        "table": "`employees`",
        "range_analysis": {
        "table_scan": { ‐‐全表扫描情况
        "rows": 10123, ‐‐扫描行数
        "cost": 2054.7 ‐‐查询成本
        } /* table_scan */,
        "potential_range_indexes": [ ‐‐查询可能使用的索引
        {
        "index": "PRIMARY", ‐‐主键索引
        "usable": false,
        "cause": "not_applicable"
        },
        {
        "index": "idx_name_age_position", ‐‐辅助索引
        "usable": true,
        "key_parts": [
        "name",
        "age",
        "position",
        "id"
        ] /* key_parts */
        }
        ] /* potential_range_indexes */,
        "setup_range_conditions": [
        ] /* setup_range_conditions */,
        "group_index_range": {
        "chosen": false,
        "cause": "not_group_by_or_distinct"
        } /* group_index_range */,
        "analyzing_range_alternatives": { ‐‐分析各个索引使用成本
        "range_scan_alternatives": [
        {
        "index": "idx_name_age_position",
        "ranges": [
        "a < name" ‐‐索引使用范围
        ] /* ranges */,
         "index_dives_for_eq_ranges": true,
         "rowid_ordered": false, ‐‐使用该索引获取的记录是否按照主键排序
         "using_mrr": false,
         "index_only": false, ‐‐是否使用覆盖索引
         "rows": 5061, ‐‐索引扫描行数
         "cost": 6074.2, ‐‐索引使用成本
         "chosen": false, ‐‐是否选择该索引
         "cause": "cost"
         }
         ] /* range_scan_alternatives */,
         "analyzing_roworder_intersect": {
         "usable": false,
         "cause": "too_few_roworder_scans"
         } /* analyzing_roworder_intersect */
         } /* analyzing_range_alternatives */
         } /* range_analysis */
         }
         ] /* rows_estimation */
         },
         {
         "considered_execution_plans": [
         {
         "plan_prefix": [
         ] /* plan_prefix */,
         "table": "`employees`",
         "best_access_path": { ‐‐最优访问路径
         "considered_access_paths": [ ‐‐最终选择的访问路径
         {
         "rows_to_scan": 10123,
         "access_type": "scan", ‐‐访问类型:为scan,全表扫描
         "resulting_rows": 10123,
         "cost": 2052.6,
         "chosen": true, ‐‐确定选择
         "use_tmp_table": true
         }
         ] /* considered_access_paths */
         } /* best_access_path */,
         "condition_filtering_pct": 100,
         "rows_for_plan": 10123,
         "cost_for_plan": 2052.6,
         "sort_cost": 10123,
         "new_cost_for_plan": 12176,
         "chosen": true
         }
         ] /* considered_execution_plans */
         },
         {
         "attaching_conditions_to_tables": {
         "original_condition": "(`employees`.`name` > 'a')",
         "attached_conditions_computation": [
         ] /* attached_conditions_computation */,
         "attached_conditions_summary": [
         {
         "table": "`employees`",
         "attached": "(`employees`.`name` > 'a')"
         }
         ] /* attached_conditions_summary */
         } /* attaching_conditions_to_tables */
         },
         {
         "clause_processing": {
         "clause": "ORDER BY",
         "original_clause": "`employees`.`position`",
         "items": [
         {
         "item": "`employees`.`position`"
         }
         ] /* items */,
         "resulting_clause_is_simple": true,
         "resulting_clause": "`employees`.`position`"
         } /* clause_processing */
         },
         {
         "reconsidering_access_paths_for_index_ordering": {
         "clause": "ORDER BY",
         "steps": [
         ] /* steps */,
         "index_order_summary": {
         "table": "`employees`",
         "index_provides_order": false,
         "order_direction": "undefined",
         "index": "unknown",
         "plan_changed": false
         } /* index_order_summary */
         } /* reconsidering_access_paths_for_index_ordering */
         },
         {
         "refine_plan": [
         {
         "table": "`employees`"
         }
         ] /* refine_plan */
         }
         ] /* steps */
         } /* join_optimization */
         },
         {
         "join_execution": { ‐‐第三阶段:SQL执行阶段
         "select#": 1,
         "steps": [
         ] /* steps */
         } /* join_execution */
         }
         ] /* steps */
         }
        
         结论:全表扫描的成本低于索引扫描,所以mysql最终选择全表扫描
        
         mysql> select * from employees where name > 'zzz' order by position;
         mysql> SELECT * FROM information_schema.OPTIMIZER_TRACE;
        
         查看trace字段可知索引扫描的成本低于全表扫描,所以mysql最终选择索引扫描
        
         mysql> set session optimizer_trace="enabled=off"; ‐‐关闭trace

group by

order by

使用最左前缀原则,这样会走索引 并且 exra是可以看到 走没走索引 如果走了索引就是 using index

比如有索引 name,age,gender

sql: select name,age from employ order by age;

上边 sql就是using filesort。代表是加载到内存或者硬盘排序。

sql: select name,age from employ order by name,age;

这个sql就是走的 using index 索引排序 因为索引本身就是排好序的。但是要最左前缀原则,不然不走索引。因为就变成无序了

sql: select name,age from employ where name = 'aa' order by age;

这个sql其实order by并没有最左前缀,因为第一个应该是name但是跳过了name。但是还是using index,因为name就是一个常量 aa ,MySQL会进行优化这样就是最左前缀了。

如果是 using filesort

代表可能是内存排序或者硬盘排序。

MySQL内存排序

因为使用的是using filesort排序,所以MySQL会先开辟出来一块内存 sort_buffer 默认1M,用来存放需要排序的数据

单双链路

mysql会通过max_length_for_sort_data

using_filesort 是将数据加载到sort_buffer中进行排序的,

单链路是将 需要排序的数据整行数据加载到sort_buffer,

双链路是将需要排序的数据主键和需要排序的字段加载到sort_buffer中进行排序,排完序再通过主键给主键索引中找到该数据。也是回表排序

mysql会通过max_length_for_sort_data 来判断使用什么排序。默认是1024字节,如果一行数据大于1024字节,那么就会走双链路排序,如果小于那就走单链路排序

单链路排序肯定比双链路排序快,因为不用回表,但是如果一行数据太大就比较占用内存所以使用双链路直接在主键和需要排序的字段。

如果sort_buffer 默认1M空间承受不了需要排序的数据,就会创建一个临时文件,先排序一部分放到文件中再取出一部分放到内存sort_buffer排序,最后合并成整个排好序的数据

MySQL索引设计原则

1、代码先行,索引后上 不知大家一般是怎么给数据表建立索引的,是建完表马上就建立索引吗? 这其实是不对的,一般应该等到主体业务功能开发完毕,把涉及到该表相关sql都要拿出来分析之后再建立 索引。

2、联合索引尽量覆盖条件 比如可以设计一个或者两三个联合索引(尽量少建单值索引),让每一个联合索引都尽量去包含sql语句里的 where、order by、group by的字段,还要确保这些联合索引的字段顺序尽量满足sql查询的最左前缀原 则。

3、不要在小基数字段上建立索引 索引基数是指这个字段在表里总共有多少个不同的值,比如一张表总共100万行记录,其中有个性别字段, 其值不是男就是女,那么该字段的基数就是2。 如果对这种小基数字段建立索引的话,还不如全表扫描了,因为你的索引树里就包含男和女两种值,根本没 法进行快速的二分查找,那用索引就没有太大的意义了。 一般建立索引,尽量使用那些基数比较大的字段,就是值比较多的字段,那么才能发挥出B+树快速二分查 找的优势来。

4、长字符串我们可以采用前缀索引 尽量对字段类型较小的列设计索引,比如说什么tinyint之类的,因为字段类型较小的话,占用磁盘空间也会 比较小,此时你在搜索的时候性能也会比较好一点。 当然,这个所谓的字段类型小一点的列,也不是绝对的,很多时候你就是要针对varchar(255)这种字段建立 索引,哪怕多占用一些磁盘空间也是有必要的。 对于这种varchar(255)的大字段可能会比较占用磁盘空间,可以稍微优化下,比如针对这个字段的前20个 字符建立索引,就是说,对这个字段里的每个值的前20个字符放在索引树里,类似于 KEY index(name(20),age,position)。 此时你在where条件里搜索的时候,如果是根据name字段来搜索,那么此时就会先到索引树里根据name 字段的前20个字符去搜索,定位到之后前20个字符的前缀匹配的部分数据之后,再回到聚簇索引提取出来 完整的name字段值进行比对。 但是假如你要是order by name,那么此时你的name因为在索引树里仅仅包含了前20个字符,所以这个排 序是没法用上索引的, group by也是同理。所以这里大家要对前缀索引有一个了解。

5、where与order by冲突时优先where 在where和order by出现索引设计冲突时,到底是针对where去设计索引,还是针对order by设计索引?到 底是让where去用上索引,还是让order by用上索引? 一般这种时候往往都是让where条件去使用索引来快速筛选出来一部分指定的数据,接着再进行排序。 因为大多数情况基于索引进行where筛选往往可以最快速度筛选出你要的少部分数据,然后做排序的成本可 能会小很多。

分页查询

在使用分页查询时,比如会写

sql select * FROM employees LIMIT 9000,10 ORDER BY id;

因为id是主键,所以是有序的,order by还比较快,但是limit MySQL是查询出来9010条数据,扔掉9000条数据,这样查询是比较慢的

我们可以使用联合索引走索引覆盖

sql select id FROM employees LIMIT 9000,10 ORDER BY id;

但是如果我们查询并不是只要id 而是id、name、age、gender。但是如果这样就不能走 覆盖索引了。

优化方案:select * FROM employees emp inner join (select id FROM employees ORDER BY id LIMIT 9000,10 ) tem ON emp.id = tem.id

这样最外层的数据使用主键关联,走的主键索引肯定很快,里面的sql走的覆盖索引不需要回表完成优化

单位遇到的优化方案: 因为是使用的id进行排序取值 可以将id返回给前端,前端分页的时候将最后一个id作为参数带给后端。 比如最后一条id=9000

sql select * FROM employees WHERE id > 9000 ORDER BY id LIMIT 10;

如果只是limit 10 条数据,回表次数也不多,我理解是不需要再去联合。这样走了主键索引而且也每次取10条。

inner查询优化 挤走索引又查询全部字段

select * FROM employees emp inner join (select id FROM employees ORDER BY id LIMIT 9000,10 ) tem ON emp.id = tem.id

上边sql 中 子查询 只返回id可以走覆盖索引不需要回表,在根据主键id联合 走主键索引找到全部数据。

这种情况我理解是需要扫描数据多,导致回表次数多,使用改方案。

NLG和BLG

比如A 有 10万条数据 B 100条数据

sql: select * from A inner join B on A.id = B.id;

MySQL会根据 联合字段有没有走索引来判断走那种算法。 比如A表中id为索引,那么就走NLG,如果不为索引,就要走无序的磁盘扫描,每扫描一次A表就相当于扫描10万行记录。所以就会走BLG

NLG

也就是索引链接。是内嵌套连接

这条sql语句执行逻辑为:

for(select id from B){

select * from A where id = B.id

}

第一步: B中去一条数据

第二步: 拿到B数据的id字段给A表中通过主键id查询 主键索引很快,几乎相当于常量查询

第三步: 在A中找到的那条数据

上边可以看出,B表越小越好,因为B越小循环次数越少。所以上边这条sql语句适合小表在后,大表在前,小表先执行,大表后执行。但是如果没有索引MySQL会执行BLG算法

假设走索引id为主键索引,如果B表中 有100条数据,A表中有100000条数据。那么执行的时候,会先全表扫描B表加载在内存中,再逐一取出一条数据去主键索引中寻找数据 。

也就是第一次全表扫描需要扫描 100 条数据,第二步通过每一条数据给A表中主键查询,每查询一次都相当于100,那么为什么给A表查询一次相当于一次查询,不应该扫描100000数据找到和取出的数据id相等的那条数据吗?那是因为主键索引非常快,通过主键索引查询非常快,几乎是常量查询,所以每查询一次主键索引相当于查询一次常量。所以 100 条数据查询完了也就相当于查询了100次A表。所以整个查询只用了200

BLG

比如上边sql中id不是索引只是普通字段。会将B表中的100行记录全表扫描放到join_buffer中。全表扫描100次,再去扫描A中10万行记录,每扫描一条就去A中join_buffer中比对id是否相同,相同就纪录下来。又因为A在join_buffer是无序的,那么就会没扫描一次A就是相当于扫描100行记录取出id和A中该数据id相等的数据。而A有需要扫描10万次,所以一共也就是 扫描A 10万次 + B 100 条 * 10万次 + 全表扫描B加入到join_buffer的100条 = 1100100 一百多万次

如果没有索引但是走NLG算法是什么样子的

索引取到B表100数据加载到 join_buffer 扫描100记录

每取出一条B表一条记录就去A表查询id相等的数据,注意这里id是普通字段不是索引。所以每查询一次就是10万条数据中找到id和当前B中取到的这条数据相等的数据。也就是 取B表100条数据需要重复 给A表10万数据查询100次也就是需要 100 * 10万 = 1000万次。并且还是磁盘扫描这么多。肯定性能不高

exit和in

exits

exit 是 select * from A where exits (select 1 from B where A.id = B.id)

相当于:

for (select * from A){

select 1 from B where B.id = A.id;

}

从上边可以看出,A表数据越小越好,因为A表越少循环次数越少,查询次数也就越少。

所以exits适合前边表小,后面表大的。

in

select * from A where A.id in (select id from B)

相当于

for(select id from B){

select * from A where A.id = B.id;

}

显然这种想要查询次数少需要B表中数据少,因为B表中数据少,就会减少循环次数从而减少查询次数。

这种数据适合于子后面表小,前边表达的sql。

count(*)、count(1)、count(字段)、count(主键)

这四种其实都是走的二级索引,因为二级索引占用内存少

如果 count(字段) 字段是索引的话: count(*)约等于 count(1) > count(字段) > count(主键)

count(*) 做了优化,就是扫描的时候,记录行数,二级索引中 扫描到一行就是 +1 不用取到某一个字段

count(1) 也是扫描到一行就 +1 不用取到某一个字段

count(字段) 因为字段是索引所以会走二级索引,所以不用回表就能取到该字段,取到这个字段才会进行+1 因为要取到 这个字段才能进行 +1 所以会比 count(*) count(1)慢

count(id) 5.7版本之前是走的主键索引,之后做了优化也是二级索引。然后取出id值进行+1

为什么 count (id) 比同是走二级索引并且 count(字段) 要慢呢?个人理解因为 count要去非叶子节点取出id,而count(字段)是扫描一条数据就是一条数据 不找非叶子节点。就可以取出字段进行+1所以会快

如果字段不走索引:

count(*)约等于 count(1) > count(主键) > count(字段)

这时候就是扫描主键索引,因为字段没有索引肯定是最慢的。

个人学习笔记,如有错误欢迎大佬指正

相关文章:

MySQL慢查询日志slowlog

慢速查询日志记录的是执行时间超过秒和检查的行数超过的SQL语句,这些语句通常是需要进行优化的。官方参考文档:https://dev.mysql.com/doc/refman/8.0/en/slow-query-log.html。

一文搞懂MySQL索引

官方介绍索引是帮助MySQL高效获取数据的数据结构。更通俗的说,数据库索引好比是一本书前面的目录,能加快数据库的查询速度。一般来说索引本身也很大,不可能全部存储在内存中,因此索引往往是存储在磁盘上的文件中的(可能存储在单独的索引文件中,也可能和数据一起存储在数据文件中)。我们通常所说的索引,包括聚集索引、覆盖索引、组合索引、前缀索引、唯一索引等,没有特别说明,默认都是使用B+树结构组织(多路搜索树,并不一定是二叉的)的索引。看到这里,你是不是对于自己的sql语句里面的索引的有了更多优化想法呢。

ON DUPLICATE KEY UPDATE 导致mysql自增主键ID跳跃增长

具体解决方案可以根据项目来选择,如果项目不大,可以考虑1和2。如果不考虑高并发问题,可以考虑3。

mysql唯一索引与null

根据NULL的定义,NULL表示的是未知,因此两个NULL比较的结果既不相等,也不不等,结果仍然是未知。根据这个定义,多个NULL值的存在应该不违反唯一约束,所以是合理的,在oracel也是如此。在mysql 的innodb引擎中,是允许在唯一索引的字段中出现多个null值的。有上面的表和数据可以看出,查询多条数据。

MySQL主从复制(基于binlog日志方式)

主从复制,是用来建立一个和主数据库完全一样的数据库环境,称为从数据库;主数据库一般是准实时的业务数据库。主从复制的作用1.做数据的热备,作为后备数据库,主数据库服务器故障后,可切换到从数据库继续工作,避免数据丢失。2.架构的扩展。业务量越来越大,I/O访问频率过高,单机无法满足,此时做多库的存储,降低磁盘I/O访问的频率,提高单个机器的I/O性能。3.读写分离,使数据库能支撑更大的并发。a.从服务器可以执行查询工作(就是我们常说的读功能),降低主服务器压力;(主库写,从库读,降压)

MYSQL 主从复制 --- binlog

在 Master 端并不 Care 有多少个 Slave 连上了自己,只要有 Slave 的 IO 线程通过了连接认证,向他请求指定位置之后的 Binary Log 信息,他就会按照该 IO 线程的要求,读取自己的 Binary Log 信息,返回给 Slave 的 IO 线程。默认MySQL是未开启该日志的。如果读压力加大,就需要更多的 slave 来解决,但是如果slave的复制全部从 master 复制,势必会加大 master 的复制IO的压力,所以就出现了级联复制,减轻 master 压力。

MySQL 中 is null 和 =null 的区别

如果 set ANSI_NULLS为 ON 时,表示SQL语句遵循SQL-92标准;如果 set ANSI_NULLS 为 OFF 时,表示不遵从 SQL-92 标准。但SQL-92 标准要求对null的 = 或不等于 (!= ,) 比较取值都为 false,也就是 =null 或者 null,返回的都是false。null 在MySQL中不代表任何值,通过运算符是得不到任何结果的,因此只能用 is null(默认情况)MySQL 中 null 不代表任务实际的值,类似于一个未知数。

MySQL数据库查询语句之组函数,子查询语句

当一个SQL的执行需要借助另一个SQL的执行结果时,则需要进行SQL嵌套,该语法结构称之为子查询。先筛选出符合要求的数据,再对符合要求的数据进行分组时,分组的工作量会被减少,效率更高。先确定从哪张表进行操作-->对表中数据进行分组-->基于分组结果进行查询操作。执行顺序:优先执行小括号内的子SQL,根据子SQL的执行结果再执行外层SQL。执行顺序:from-->where-->group by-->select。执行顺序:from-->group by-->select。

mysql开启可以使用IP有权限访问

为实际的IP地址和你想要设置的密码。请小心操作,并确保你了解每个命令的作用。如果你对此有任何疑问,最好咨询经验丰富的数据库管理员。来设置或修改用户的密码。相反,你需要分两步来完成这个过程:首先创建或修改用户,并设置密码;然后授予相应的权限。用户应该能够从指定的内网IP地址访问MySQL服务器。用户已存在并且你只是想更改其密码或允许从另一个地址访问,使用。在MySQL 8.0及更高版本中,语句的语法有所变化。替换为你的内网IP地址,

雪花算法生成ID、UUID生成ID和MySql自增ID优缺点分析

综上所述,UUID适用于分布式系统和需要保密的场景,雪花ID适用于分布式系统和高并发环境,MySQL自增ID适用于单机系统和高效查询的场景。根据具体的业务需求和系统架构,选择合适的主键类型。通过本文的介绍和对比,希望读者能够更好地理解在MySQL中不推荐使用UUID或者雪花ID作为主键的原因,并能够根据实际情况做出明智的选择。在MySQL中,使用自增整数作为主键是一种常见的做法,因为它具有较小的存储空间、高效的索引和自动增长的特性。然而,具体选择何种主键类型还是要根据具体的业务需求和数据特点来决定。

【小白专用】C# 连接 MySQL 数据库

C# 连接 MySQL 数据库

如何用pthon连接mysql和mongodb数据库【极简版】

发现宝藏 前言 1. 连接mysql 1.1 安装 PyMySQL 1.2 导入 PyMySQL 1.3 建立连接 1.4 创建游标对象 1.5 执行查询 1.6 关闭连接 1.7 完整示例 2. 连接mongodb 2.1 安装 PyMongo 2.2 导入 PyMongo 2.3 建立连接 2.4

《mybatis》--大数据量查询解决方案

之前写百万以及千万的导出数据的时候,对于将数据写道csv文件并压缩这里没有什么大问题了,但是出现了其他问题为:1、我们需要将数据从数据库中拿出来,并且在进行装配的时候出现了一些问题。2、对于整体内存安全来说,如果直接将数据从数据库中拿出来百万级别以上的数据对于内存是非常不友好的。当问题出现比较大的时候会直接触发GC,造成瘫痪。目前开发以及项目测试的是更多的使用mybatis来进行开发的,所以本文章讨论以及解决的的就是如何使用mybaits来解决流式查询并单条处理的问题。

ClickHouse 与mysql等关系型数据库对比

先用一张图帮助理解两者的本质上的区。

Windows安装MySQL及网络配置

向日葵软件是一种远程控制软件,可以让用户在不同设备之间进行远程桌面访问和文件传输。用户可以通过向日葵软件,在任何具有互联网连接的设备上远程控制其他设备,包括计算机、智能手机和平板电脑。用户只需安装向日葵软件,并使用登录凭据连接到目标设备,就可以实时控制目标设备上的屏幕、键盘和鼠标。向日葵软件还提供了一些辅助功能,如文件传输、远程打印和远程会议等。这使得向日葵软件成为一个方便实用的远程协助工具,适用于个人用户、技术支持人员和企业用户等各种场景。

深入理解Mysql事务隔离级别与锁机制

我们的数据库一般都会并发执行多个事务,多个事务可能会并发的对相同的一批数据进行增删改查操作,可能就会导致我们说的脏写、脏读、不可重复读、幻读这些问题。这些问题的本质都是数据库的多事务并发问题,为了解决多事务并发问题,数据库设计了事务隔离机制、锁机制、MVCC多版本并发控制隔离机制,用一整套机制来解决多事务并发问题。接下来,我们会深入讲解这些机制,让大家彻底理解数据库内部的执行原理。

MySQL是如何保证数据不丢失的?

上篇文章《InnoDB在SQL查询中的关键功能和优化策略》对InnoDB的查询操作和优化事项进行了说明。但是,MySQL作为一个存储数据的产品,怎么确保数据的持久性和不丢失才是最重要的,感兴趣的可以跟随本文一探究竟。

where查询条件的字段顺序打乱会影响命中索引吗?

答案是:不影响我们的where后边条件字段打乱会影响命中索引吗?先来进行下边的实验:可以看到实验结果,where条件字段顺序没有按照索引的字段顺序,依然不影响命中索引。因为Mysql中有查询优化器,会自动优化查询顺序。

MySQL删除会走索引吗

MySQL是关系型数据库管理系统的一种, 网站在进行数据的增删改查的时候,我们往往需要使用 MySQL 数据库。而删除操作就是在 MySQL 数据库中删除指定的数据或者表格的操作。

Linux多种方法安装MySQL

源码安装:优点是安装包比较小,只有十多M,缺点是安装依赖的库多,安装编译时间长,安装步骤复杂容易出错。使用官方编译好的二进制文件安装:优点是安装速度快,安装步骤简单,缺点是安装包很大,300M左右。yum安装。rpm安装。

Linux中mysql 默认安装位置&Linux 安装 MySQL

MySQL在Linux系统上的默认安装位置是目录。这是MySQL服务器的数据目录,包含所有数据库文件。通过检查MySQL二进制文件的路径,我们可以确认MySQL是否正确安装。在目录中,MySQL使用一系列文件和子目录来组织和存储数据。确保理解MySQL数据目录的结构对于管理和维护MySQL数据库至关重要。按照顺序安装即可解决。

MySQL数据库索引以及使用唯一索引实现幂等性

一次和多次请求某一个资源对于资源本身应该具有同样的结果任意多次执行对资源本身所产生的影响均与一次执行的影响相同。

【微服务】mysql + elasticsearch数据双写设计与实现

在很多电商网站中,对商品的搜索要求很高,主要体现在页面快速响应搜索结果。这就对服务端接口响应速度提出了很高的要求。

基于 MySQL 多通道主主复制的机房容灾方案

文章中介绍了多种 MySQL 高可用技术,并介绍了根据自身需求选择多通道主主复制技术的过程和注意事项。

MySQL中的 增 删 查 改(CRUD)

文章浏览阅读1.8k次,点赞60次,收藏56次。insert into 表名 value(数据,数据),.......;可以单行,多行插入。​为查询结果的列取别名select 表达式/列名as 别名 from 表名;去重:DISTINCTselect distinct 单列/多列 from 表名;会去除查询结果中的重复项(只保留一项)select 条件查询的执行顺序遍历表中的每个记录把当前记录的值带入条件,根据条件进行筛选如果这条记录满足条件,保留并进行列上的表达式的计算如果有 order by 会在所有行都被获取到之后(表​

【MySQL从删库到跑路 | 基础第二篇】——谈谈SQL中的DML语句

详细介绍SQL中的DML语句(增加、修改、删除操作)。

【MySQL基础|第三篇】--- 详谈SQL中的DQL语句

详解MySQL中SQL的基础查询、条件查询、聚合函数、分组查询、排序查询、分页查询。

【MySQL函数篇】—— 字符串函数(超详细)

详细介绍MySQL函数中的字符串函数。

MySQL常用函数集锦 --- 字符串|数值|日期|流程函数总结

主要讲解MySQL中的字符串、日期、数值、流程函数。

详细介绍MySQL中的六种约束

详细介绍MySQL中的六种约束