MySQL_MySQL查询截取分析之小表驱动大表

1.引入

  我们之前和大家讲解了索引的基本内容以及索引的优化,那么下面呢我们就进入我们的下一个部分的内容:查询截取分析。我们在使用我们的MySQL进行实际操作的时候,是如何进行MySQL数据库优化查询的分析呢?一般我们都会经过如下的步骤:

(1).运行系统,观察一段时间(一般需要大于1天),看看执行慢的SQL情况。

(2).开启慢查询日志。通过这只执行的阈值,如执行时间超过几秒的就定义为慢SQL(具体几秒按照系统的情况而定),并把它抓取出来。

(3).使用explain + 慢SQL分析。

一般的情况,我们通过上述的操作以后就基本可以查询出SQL中存在的问题了。但是如果还没有解决问题。那么这一个时候我们就需要更加深入的进行分析。

(4).show profile。(这一个操作一般就是运维经理或者是DBA,来进行SQL数据库服务器的参数优化)。

 

2.小表驱动大表

   为什么说在数据库中的操作是需要小表来驱动大表?好,我们呢一起来看一下的这一个操作:

//一个简单的嵌套循环(A)

for(int i = 0 ; i < 100; i ++)
{
  for(int j  = 0 ; j < 20; j ++)
  {
    System.out.println("Hello world");
  }

}

//另一个简单的嵌套循环(B)

for(int i = 0 ; i < 20; i ++)
{
  for(int j  = 0 ; j < 100; j ++)
  {
    System.out.println("Hello world");
  }

}

分析:
    俩个程序的输出结果都是一样的,在一般的Java程序中没有多大的区别,但是在MySQL的执行中却有较大的区别!,为什么呢?
    我们可以这样理解这一个问题。我们使用java程序去操作数据库内容,我们需要和数据库建立连接的通道,查询完毕以后,我们需要再次关闭数据库的连接。但是呢如果说在较短的时间需要和数据库建立很多次的连接,但是你每一次连接都只做了一个简单的查询。这一个时候你就会占用MySQL数据库的资源。但是其达到的效果确是很低的。但是你反过来,一个连接我们就能够在MySQL数据库上进行很多的操作。那么这样我们就把MySQL的资源充分的利用起来了。这就是为什么需要小表驱动大表。

3.小表驱动大表的使用:in关键字和exists关键字的相关使用:

(1).创建数据库表:

  图书库存表(bookstore)

图书信息表(book)

俩表通过字段bookstore_id进行关联。

(2).使用In关键字进行俩表的查询

SQL:

select * from book where bookstore_id in(select bookstore_id from bookstore);

等价于:

for : select bookstore_id from bookstore;

for : select * from book where book.bookstore_id = bookstore.bookstore_id;

(3).使用exists关键字进行俩表的查询

SQL:

select * from book where exists (select 1 from bookstore where bookstore.bookstore_id = book.bookstore_id);

等价于:

for:  select * from book;

for:  select * from bookstore where bookstore.bookstore_id = book.bookstore_id;


这个语法可以这样理解:
    将主查询的数据,放到子查询中做条件验证。根据验证的结果(true或者是false)来决定查询的数据是否可以保留。

(4).使用in关键字或者是exists哪一种更加好呢?

当bookstore表的数据集必须小于book表的数据集时,使用in优于exists。

当book表的数据集必须小于bookstore表的数据集时,使用exists优于in。

同时,我们应该在book表和bookstore表的bookstore_id 上建立相关的索引。

 

(5).总结:

①.exists关键字的查询只返回一个布尔类型的数据(true/false).这样就导致select * 也可以是select + 常量。或者是是实际执行的时候会忽略select清单。因此是没有区别的。

②.exists关键字子查询的实际执行过程可能会经过优化,而不是我们理解的逐条对比。如担心效率的问题。可以进行实际验证确定是否有效。

③..exists关键字子查询往往可以使用条件表达式、其他子查询或者是JOIN来替代。

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
首先,我们需要使用 Flink Kafka Consumer 从大主题中读取数据。然后,我们可以使用 KeyedStream 将数据按照 key 分组,然后使用 Flink Kafka Producer 将数据写入多个小主题。同时,我们也可以将数据写入 MySQL 数据库。下面是一个简单的示例程序: ```java import org.apache.flink.api.common.serialization.SimpleStringSchema; import org.apache.flink.streaming.api.datastream.DataStream; import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment; import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer; import org.apache.flink.streaming.connectors.kafka.FlinkKafkaProducer; import org.apache.flink.streaming.connectors.kafka.KafkaSerializationSchema; import org.apache.flink.streaming.connectors.kafka.KafkaSink; import org.apache.flink.streaming.util.serialization.KeyedSerializationSchema; import org.apache.kafka.clients.producer.ProducerConfig; import org.apache.kafka.clients.producer.ProducerRecord; import org.apache.kafka.common.serialization.StringSerializer; import java.util.Properties; public class KafkaSplitter { public static void main(String[] args) throws Exception { final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); // 从大主题中读取数据 Properties kafkaProps = new Properties(); kafkaProps.setProperty("bootstrap.servers", "localhost:9092"); kafkaProps.setProperty("group.id", "my-group"); FlinkKafkaConsumer<String> consumer = new FlinkKafkaConsumer<>("big-topic", new SimpleStringSchema(), kafkaProps); DataStream<String> stream = env.addSource(consumer); // 根据 key 分组 DataStream<String> keyedStream = stream.keyBy(line -> line.split(",")[0]); // 写入多个小主题 Properties producerProps = new Properties(); producerProps.setProperty("bootstrap.servers", "localhost:9092"); FlinkKafkaProducer<String> kafkaProducer = new FlinkKafkaProducer<>("small-topic", new SimpleStringSchema(), producerProps, KafkaSerializationSchema::get); keyedStream.addSink(kafkaProducer); // 写入 MySQL 数据库 keyedStream.addSink(new MySQLSink()); env.execute("KafkaSplitter"); } public static class MySQLSink extends RichSinkFunction<String> { private Connection connection; @Override public void open(Configuration parameters) throws Exception { super.open(parameters); Class.forName("com.mysql.jdbc.Driver"); connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "username", "password"); } @Override public void close() throws Exception { super.close(); if (connection != null) { connection.close(); } } @Override public void invoke(String line, Context context) throws Exception { String[] fields = line.split(","); String key = fields[0]; String value = fields[1]; PreparedStatement statement = connection.prepareStatement("INSERT INTO mytable (key, value) VALUES (?, ?)"); statement.setString(1, key); statement.setString(2, value); statement.executeUpdate(); } } } ``` 在上面的示例程序中,我们使用了 Flink Kafka Consumer 和 Flink Kafka Producer 来读取和写入 Kafka 主题。我们还实现了一个自定义的 MySQLSink,在其中将数据写入 MySQL 数据库。注意,我们需要将 MySQL 驱动程序添加到 Maven 依赖中。 ```xml <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.26</version> </dependency> ``` 使用这个程序,我们可以将一个大的 Kafka 主题拆分成多个小主题,并将数据写入 MySQL 数据库
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

魔笛手7

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值