关于MySQL的索引,这些知识你都理解了吗

在这里插入图片描述

1、概述

  • 创建索引时, 需要确保该索引是引用在SQL查询语句的条件(一般作为WHERE子句的条件)
  • 索引也是一张表, 保存了主键和索引字段,并指向实体表的记录
  • 索引提高了查询速度,但会拉低更新表的速度,并且会占用额外的磁盘空间

2、索引的类别
图片

索引的类别

Primary Key (聚集索引):

InnoDB存储引擎的表会存在主键(唯一非null), 如果建表时没有指定则会使用第一非空的唯一索引作为聚集索引,否则InnoDB会自动帮你创建一个不可见的、长度为6字节的row_id用来作为聚集索引。

02 构造mysql百万条数据

  • Unique(唯一索引):

    索引列的值必须唯一,但允许有控制

  • FULLTEXT(全文索引):

    在定义索引的列上支持值的全文查找

  • SPATIAL(空间索引)

索引创建的原则

索引并非越多越好,一个表中如果有大量的索引,会占用额外的空间和影响更新的性能,因为表在数据更改的同时,索引也会进行调整和更新

避免对经常更新的表进行索引

数据量小的表不要使用索引,数据少时遍历索引的时间可能比查询的时间更长

在条件表达式中常用到的不同值较多的列上建立索引,在不同值很少的列上不要建立索引。

使用唯一索引能确保定义的列的数据完整性

在频繁进行排序或分组的列上建立索引,如果待排序列有多个,可以在这些列上建立组合索引

搜索的索引列不一定是所要选择的列,最适合索引的列式出现在WHERE子句中的列

使用短索引

利用最左前缀

构造数据

package com.example.sql;

import java.sql.*;

import java.util.Random;

/**

 * JDBC生成100万条假数据
 */public class DataInjection {
    public static void main(String[] args) throws SQLException {
        String url = "jdbc:mysql://localhost:3306/test?useSSL=false";
        String user = "root";
        String password = "password";

        // 数据注入相关信息//        String[] names = new String[]{"Ali", "Annie", "Eric", "Rob", "Bob", "Amber"};
        Connection conn = DriverManager.getConnection(url, user, password);
        PreparedStatement preparedStatement = conn.prepareStatement("insert into `demo` values (?, ? ,?, ?,?)");
        Random random = new Random();
        long startTime = System.currentTimeMillis();

        for (int i = 1; i < 2000001; i++){
            String id = String.valueOf(i);
            String name = "UserNickName" + i + random.nextInt(1000);
            int age = random.nextInt(81);
            String content = "randomContent:" + System.currentTimeMillis() + random.nextInt(1000);
            preparedStatement.setString(1, id);
            preparedStatement.setString(2, name);
            preparedStatement.setInt(3, age);
            preparedStatement.setString(4, content);
            preparedStatement.setString(5, String.valueOf(System.currentTimeMillis()));
            preparedStatement.addBatch();
            if(i % 2000 == 0){ // 每两千条插入一次
                preparedStatement.executeBatch();
                System.out.println("计数:" + i);
            }
        }

        long endTime = System.currentTimeMillis();
        long diff = endTime - startTime;
        long hour = diff / 3600000;
        System.out.println("耗时:" + diff);
        preparedStatement.close();
        conn.close();
    }}

03 查询测试

1、没有添加索引

select * from demo where age > 30;

图片

图片

2、添加Primary key

图片

图片

3、为age列添加index

图片

图片

图片

4、Spring输出测试

package com.example.demo.controller;

import com.example.demo.domain.User;

import org.springframework.jdbc.core.JdbcTemplate;

import org.springframework.jdbc.core.RowMapper;

import org.springframework.stereotype.Controller;

import org.springframework.ui.ModelMap;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;

import javax.servlet.ServletOutputStream;

import javax.servlet.http.HttpServletResponse;

import java.io.*;

import java.nio.charset.StandardCharsets;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.util.List;



@Controller

@RequestMapping("/jdbc")



public class JdbcController {

   @Resource
    private JdbcTemplate jdbcTemplate;    /**
     * 封装成User对象直接返回
     * @param map
     * @return
     * @throws FileNotFoundException
     */    
    @RequestMapping("/user")
    @ResponseBody
    public List<User> list(ModelMap map) throws FileNotFoundException {
        String sql = "Select * from demo where age > 50";
        List<User> users = jdbcTemplate.query(sql, new RowMapper<User>() {
            @Override
            public User mapRow(ResultSet resultSet, int i) throws SQLException {
                User user = new User();
                user.setId(resultSet.getString("id"));
                user.setName(resultSet.getString("name"));
                user.setAge(resultSet.getInt("age"));
                return user;
            }
        });
        for (User user : users){
            System.out.println(user);
        }
        return users;
    }    /**
     * 用流将数据写成文件通过下载返回
     * @param response
     * @throws IOException
     */
    @GetMapping("/string")//    @ResponseBody
    public void getAll(HttpServletResponse response) throws IOException {
        String sql = "Select * from demo where age > 30";
        StringBuilder sb = new StringBuilder(); //
        List<User> users = jdbcTemplate.query(sql, new RowMapper<User>() {
            @Override
            public User mapRow(ResultSet resultSet, int i) throws SQLException {
                User user = new User();
                user.setId(resultSet.getString("id"));
                user.setName(resultSet.getString("name"));
                user.setAge((resultSet.getInt("age")));
                user.setContent(resultSet.getString("content"));
                user.setTimestamp(resultSet.getString("timestamp"));
                sb.append("user" + resultSet.getString("id"));
                sb.append("name" + resultSet.getString("name"));
                sb.append("age" + resultSet.getString("age"));
                sb.append("content" + resultSet.getString("content"));
                sb.append("timestamp" + resultSet.getString("timestamp"));
                return user;
            }
        });
        // 设置请求参数
        response.setContentType("application/x-download"); // 以下载的方式传输
        response.setHeader("Content-Disposition", "attachment; filename=test.txt"); // 设置文件名
        response.setContentLength(sb.length()); // 设置响应文件大小
        ServletOutputStream out = response.getOutputStream(); // 开启流
        out.write(sb.toString().getBytes(StandardCharsets.UTF_8)); // 输出
        out.flush();
        out.close();;

    }}

下面是一份配套资料,对于做【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!
在这里插入图片描述
这些都可以在公众号:伤心的辣条 ! 免费领取,还有一份216页软件测试工程师面试宝典文档资料。以及相对应的视频学习教程免费分享!,其中资料包括了有基础知识、Linux必备、Shell、互联网程序原理、Mysql数据库、抓包工具专题、接口测试工具、测试进阶-Python编程、Web自动化测试、APP自动化测试、接口自动化测试、测试高级持续集成、测试架构开发测试框架、性能测试、安全测试等。

学习不要孤军奋战,最好是能抱团取暖,相互成就一起成长,群众效应的效果是非常强大的,大家一起学习,一起打卡,会更有学习动力,也更能坚持下去。你可以加入我们的测试技术交流扣扣群:914172719(里面有各种软件测试资源和技术讨论)

喜欢软件测试的小伙伴们,如果我的博客对你有帮助、如果你喜欢我的博客内容,请 “点赞” “评论” “收藏” 一键三连哦!


好文推荐

转行面试,跳槽面试,软件测试人员都必须知道的这几种面试技巧!

面试经:一线城市搬砖!又面软件测试岗,5000就知足了…

面试官:工作三年,还来面初级测试?恐怕你的软件测试工程师的头衔要加双引号…

什么样的人适合从事软件测试工作?

那个准点下班的人,比我先升职了…

测试岗反复跳槽,跳着跳着就跳没了…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值