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(里面有各种软件测试资源和技术讨论)
喜欢软件测试的小伙伴们,如果我的博客对你有帮助、如果你喜欢我的博客内容,请 “点赞” “评论” “收藏” 一键三连哦!
好文推荐
转行面试,跳槽面试,软件测试人员都必须知道的这几种面试技巧!