性能测试:数据库架构和SQL优化

2023-05-16

前言
有时候我们出去面试的时候,会被问到是否有做过架构方面的优化。如果没有准备突然被问到的话通常会有点懵。那么我们这里来整理一下系统架构优化相关的知识。

其实一般架构优化主要就分为数据库架构,第二个就是应用程序架构。
数据库架构优化

  1. 读写分离,主从配置

数据库架构优化,其实主要就是读写分离,主从配置。通常公司并发量比较大,或者用户比较大的情况下都会考虑读写分离。数据库支持主从同步,一台机器作为主,一台机器作为从。一旦做成主从就可以实现读写分离。一般读写分离通常是读的操作放在从机上,写的操作放在主机上,这样当我们往主上面写入数据的时候,它会向从同步数据。

这样相当于我们把一个数据库的工作分担到两台数据库上,这样子每个数据的压力会降低,我们数据库的性能就会提升。

  1. 分库分表

然后一种数据库架构优化是分库分表。为什么要做分库分表呢?
MYSQL当它单表的数据达到某个值的时候,他的性能就会比较厉害。(通常单张表超出2-3千万),那么当大数据的情况下,分库分表就非常重要。分库分表会根据一个固定的算法来路由库名和表名。

这样子就相当于我们把数据平均拆分到某干个表中,每个表的单表容量就会降低。而且分表通常都会结合着分库,分库分表我们需要用到数据库中间件。
数据库硬件优化
使用更好的物理磁盘介质,如 SSD、fusionIO卡 等。通常公司比较核心的数据库用的都是比较好的磁盘。
SQL优化
说到数据库的话,我们不得不说到SQL,下面我们来看一下常见的一些SQL优化方案:

  • whereorder by 设计到列上建立索引,避免全表扫描,索引不要太多,一个表一般不要超过4个索引。
  • 避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引进行全局扫描。如果想要判断null值,可以使用EXISTS来判断
  • 避免在 where 子句中对字段进行函数或者表达式操作,否则导致引擎放弃使用索引进行全局扫描,可以将函数或者表达式放在代码层进行判断。
  • 避免在 where 子句中对字段进行左右模糊查询,否则导致引擎放弃使用索引进行全局扫描,如下sql
1|select name from user where name like '%test%';

当我们数据量大的时候,模糊查询的功能就不应该在数据库层面做了,可以使用搜索引擎ES

  • 查询语句中尽量不要使用 * ,减少内存的使用
  • 尽量减少子查询,使用关联查询(left join,right join,inner join)代替
  • 减少使用 in 或者 not in,使用 exists, not exists或者关联查询语句代替
  • or 的查询尽量用 union 或者 union all 代替,如下SQL
# 如我们想要查询id 为12的数据
select * from user where id = 1 or id = 2

# 我们可以使用UNION代替,他们的查询效果是一样的,但是UNION的性能会更好
# UNION会自动去除重复数据
select * from user where id = 1 
UNION
select * from user where id = 2
  • 合理的添加冗余的字段(减少表的联接查询)
  • 建表的时候能使用数字类型的字段就使用数字类型(type,status…),数字类型的字段作为条件查询比字符串快
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

性能测试:数据库架构和SQL优化 的相关文章

  • PDO::PARAM_FLOAT 不存在,为什么?

    我想知道为什么 PDO PARAM FLOAT 不存在以及什么可以替代它 没有 可能是由于隐含的舍入问题 只需使用PDO PARAM STR并使用将浮点数转换为字符串strval float or string float
  • VB SQL 语句未选择正确的行

    我试图使用 SELECT 语句在我的数据库中 选择 一个人 但它没有选择正确的人 我也不确定为什么 我正在使用访问数据库 数据库连接代码 Imports System Data OleDb Module Database Connectio
  • 如何使组合键唯一?

    I am making a database of students in one school Here is what I have so far 如果您不喜欢阅读 请跳至 简而言之 部分 问题是我对这个设计并不满意 我想要的组合gra
  • 仅当所有记录都匹配时 SQL 连接

    我有3张桌子 CP carthead idOrder CP cartrows idOrder idCartRow CP shipping idCartRow idShipping dateShipped 每个 idOrder 可以有多个 i
  • 尝试通过比较不同的表从 SQL 查询输出正确的值

    我对 SQL 非常陌生 需要有关如何使用正确的查询完成此任务的帮助 我有 2 张桌子需要使用 表 TB1 有 id Name 1 bob 2 blow 3 joe 表 TB2 有 compid property 1 bob 2 blow 我
  • Crystal Reports 相当于“WHERE”

    我熟悉 SQL 但不熟悉 Crystal Reports 我正在尝试处理包含 5 列的导入数据集 id deathDate giftDate giftAmount Dead 123 2008 01 06 2011 09 08 25 00 T
  • 什么时候应该使用 XML 而不是 SQL? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • SQL/C# - UPSERT 上的主键错误

    UPDATE 简化的问题 从问题中删除了 C 在以下情况下 如何编写一个可以识别两行相同的 UPSERT 看看怎么有一个 b 退格键 在那里编码 奇怪的小字符 SQL 将它们视为相同 虽然我的 UPSERT 将此视为new data并在应该
  • 显式与隐式 SQL 连接

    显式内连接与隐式内连接之间有效率差异吗 例如 SELECT FROM table a INNER JOIN table b ON a id b id vs SELECT a b FROM table a table b WHERE a id
  • 实体框架 - 查询可为空列时出现问题

    我在从具有可为空的tinyint 列的表中查询数据时遇到问题 问题似乎是查询生成为 AND CAST Extent1 PositionEffect AS int p linq 3 gt p linq 3 NULL 如果我手动运行该查询 它不
  • Django 查询:“datetime + delta”作为表达式

    好吧 我的问题如下 假设我有下一个模型 这是一个简单的情况 class Period models Model name CharField field specs here start date DateTimeField field s
  • 将错误保存到 MySQL 数据库

    我有一个 php 查询来更新 MySQL 数据库 请参见下文 sql update hr payroll set payroll number payroll number tax code tax bacs ref bacs ref pa
  • SQL如何将两个日期之间一小时内的事件相加并显示在一行中

    我正在使用 C 和 SQL Server 2005 开发一份报告 我只需显示我们每小时获得的点击次数 桌子很大 输出应如下所示 Row Date Time Hit Count 1 07 05 2012 8 00 3 2 07 05 2012
  • 如何避免这两个 SQL 语句之间出现死锁?

    我有两个存储过程在单独的线程中运行 在 SQL Server 2005 上运行 一个过程将新行插入到一组表中 另一个过程从同一组表中删除旧数据 这些过程在表上遇到了死锁DLevel and Model 这是架构 source barrams
  • 对带有空白 NVARCHAR 或 NULL 检查的 VARCHAR 索引进行 Count(*) 会导致返回的行数加倍

    我有一张桌子 上面有VARCHAR列及其上的索引 每当一个SELECT COUNT 是在这张表上完成的 该表检查了COLUMN N OR COLUMN IS NULL它返回双倍的行数 SELECT 与相同的where子句将返回正确的记录数
  • 在 MySQL 中插入时检查并防止相似字符串

    简要信息 我有3张桌子 Set id name SetItem set id item id position TempSet id 我有一个函数可以生成新的随机组合Item桌子 基本上 总是在成功生成之后 我在中创建一个新行Set表 获取
  • 如何在Oracle中从表中选择列,*?

    我正在创建很多脚本 有时为了检查表是否根据我的需要进行更新 我会即时编写几个 SELECT 语句 在 SQL SERVER 中你可以这样写 SELECT Column1 FROM MY TABLE 出于可见性原因 这很有用 但是这似乎在 O
  • 通过Java从MySQL中获取大量记录

    有一个 MySQL 表 服务器上的用户 它有 28 行和 100 万条记录 也可能会增加 我想从这个表中获取所有行 对它们进行一些操作 然后将它们添加到 MongoDB 中 我知道通过简单的 从用户中选择 操作来检索这些记录将花费大量时间
  • 更新 SQLAlchemy 中的特定行

    我将 SQLAlchemy 与 python 一起使用 我想更新表中等于此查询的特定行 UPDATE User SET name user WHERE id 3 我通过 sql alchemy 编写了这段代码 但它不起作用 session
  • 有没有办法在 MySQL 中有效地对 TRUNCATE 或 DROP TABLE 进行 GRANT ?

    我最近在 MySQL 5 5 x 中尝试过 GRANT SELECT INSERT UPDATE DELETE TRUNCATE ON crawler TO my user localhost WITH GRANT OPTION 这会导致错

随机推荐