yin

yin 查看完整档案

成都编辑成都信息工程大学  |  软件工程 编辑  |  填写所在公司/组织 www.cdeason.cn 编辑
编辑

毕业3年菜鸡,立志努力学习进入大厂

个人动态

yin 赞了文章 · 2019-12-31

不能用 + 拼接字符串? 这次我要吊打面试官!

好久没维护《吊打面试官》系列了,今天再来一篇,这次真的要吊打了,哈哈!(看往期吊打系列请在后台回复:吊打,我会陆续更新……)

我们做 Java 程序员以来,不管是工作当中,还是面试过程中,都知道:字符串拼接不能用 String,要用 StringBuilder 或者是 StringBuffer,以至于它们都被滥用了。

StringBuilder、StringBuffer 简称:SB,下文统一用 SB 代替。

SB它们都是可变的字符串,它们之间的区别也是 Java 初中级面试战场上出现几率十分高的一道题,上场率没有 90% 也有 80% 吧。

这两个的具体区别请看这篇文章:StringBuffer 和 StringBuilder 的 3 个区别

我们反过来想下,String真的是不可变的么?不一定,看下这篇:Java 中的 String 真的是不可变的吗?

当然,本文不是讨论字符串可变与不可变的问题,而是讨论:字符串拼接一定要用 SB 吗?为什么不能用 + ?能不能用 + ?什么时候可以用 +

为什么不能用 + 号拼接字符串?我不服,接下来我要吊打面试官!

什么时候不能用 +

通过多个表达式完成一个字符串拼接操作。

private void test1() {
    String www = "www.";
    String str = www;
    str += "javastack.";
    str += "com";
}

字节码如下:

// access flags 0xA
private static test2()V
L0
LINENUMBER 14 L0
LDC "www."
ASTORE 0
L1
LINENUMBER 15 L1
ALOAD 0
ASTORE 1
L2
LINENUMBER 16 L2
NEW java/lang/StringBuilder
DUP
INVOKESPECIAL java/lang/StringBuilder.<init> ()V
ALOAD 1
INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
LDC "javastack."
INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
INVOKEVIRTUAL java/lang/StringBuilder.toString ()Ljava/lang/String;
ASTORE 1
L3
LINENUMBER 17 L3
NEW java/lang/StringBuilder
DUP
INVOKESPECIAL java/lang/StringBuilder.<init> ()V
ALOAD 1
INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
LDC "com"
INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
INVOKEVIRTUAL java/lang/StringBuilder.toString ()Ljava/lang/String;
ASTORE 1
L4
LINENUMBER 18 L4
RETURN
L5
LOCALVARIABLE www Ljava/lang/String; L1 L5 0
LOCALVARIABLE str Ljava/lang/String; L2 L5 1
MAXSTACK = 2
MAXLOCALS = 2

不会查看字节码的,看这里:3种骚操作,教你查看 Java 字节码,看这一篇就会了。

观察下,NEW java/lang/StringBuilder 出现了两次,是因为我们在代码中拼接了两次,也就是说每一次拼接操作都会创建一次 StringBuilder

如果我们是在一个循环中进行字符串拼接,那是不是一次拼接就要创建一个 StringBuilder

wtf……这哪能接受!频繁创建对象是有性能开销的,这也是为什么我们常说的字符串不能用 + 拼接,而要用那两个 SB 拼接了。

什么时候可以用 +

直接将三个字面量的字符串拼接成一个字符串。

private static void test2() {
    String str = "www." + "javastack." + "com";
}

字节码如下:

// access flags 0x2
private test2()V
L0
LINENUMBER 13 L0
LDC "www.javastack.com"
ASTORE 1
L1
LINENUMBER 14 L1
RETURN
L2
LOCALVARIABLE this Lcom/test/jdk/TestSB; L0 L2 0
LOCALVARIABLE str Ljava/lang/String; L1 L2 1
MAXSTACK = 1
MAXLOCALS = 2

从字节码看出,没有任何创建 StringBuilder 的指令,直接从常量池进行取出一个完整的字符串:www.javastack.com。很明显,这是 Java 编译器对代码进行了优化。

所以,通过这个示例告诉你,在这种情况下是可以用 + 号进行字符串拼接的。

这个示例可以演变成我们实际工作当中的某个 SQL 语句拼接的案例,如:

String sql = "select name, sex, age, address"
        + "from t_user"
        + "where age > 18";

别说这样不行,这样是行的。

但你要是换成这样就不行了:

String sql = "select name, sex, age, address";
sql += "from t_user";
sql += "where age > 18";

这样又回到创建多个 StringBuilder 的时候了。

也就是说,在一个表达式中完成字符串拼接是可以用 + 号完成的,因为编译器已经做了优化。

小结一下

你只需要记住这两点:

1、在循环和多个表达式中不能 +,频繁创建 SB 性能影响;

2、在单个表达式中可以用 +,编译器直接做了优化;

老铁们,都搞清楚了?

这个观点有没有被误解很久?

下次面试,把这篇内容亮出来,吊打面试官,没问题的。

有收获的朋友一定要点个在看,这样我写原创更带劲了,谢了,老铁们。

关注Java技术栈微信公众号,栈长将继续分享好玩的 Java 技术,公众号第一时间推送,在公众号后台回复:Java,可以获取历史 Java 教程,都是干货。

查看原文

赞 4 收藏 3 评论 0

yin 发布了文章 · 2019-08-28

leetcode刷题记录

我的博客地址
我的leetcode GitHub地址:leetcode记录
先从数组-简单开始,已完成如下
2019-08-27:1.两数之和26.删除排序数组中的重复项
2019-08-28:27.移除元素35.搜索插入位置

查看原文

赞 0 收藏 0 评论 0

yin 发布了文章 · 2019-07-23

Leetcode 题解 - 双指针

一、有序数组的 Two Sum

Input: numbers={2, 7, 11, 15}, target=9
Output: index1=1, index2=2

题目描述:在有序数组中找出两个数,使它们的和为 target。

解题思路:使用双指针,一个指针指向值较小的元素,一个指针指向值较大的元素。指向较小元素的指针从头向尾遍历,指向较大元素的指针从尾向头遍历。

如果两个指针指向元素的和 sum == target,那么得到要求的结果;
如果 sum > target,移动较大的元素,使 sum 变小一些;
如果 sum < target,移动较小的元素,使 sum 变大一些。


import java.util.Arrays;

/**
 * Input: numbers={2, 7, 11, 15}, target=9
 * Output: index1=1, index2=2
 * 题目描述:在有序数组中找出两个数,使它们的和为 target。
 *
 * 使用双指针,一个指针指向值较小的元素,一个指针指向值较大的元素。指向较小元素的指针从头向尾遍历,
 * 指向较大元素的指针从尾向头遍历。
 *
 * 如果两个指针指向元素的和 sum == target,那么得到要求的结果;
 * 如果 sum > target,移动较大的元素,使 sum 变小一些;
 * 如果 sum < target,移动较小的元素,使 sum 变大一些。
 */
public class TwoSum {
    public static int[] towSum(int[] numbers, int target){
        int i = 0;
        int j = numbers.length - 1;
        int sum;
        while(i < j){
            sum = numbers[i] + numbers[j];
            if(sum > target){
                j--;
            }else if(sum < target){
                i++;
            }else{
                return new int[]{i+1,j+1};
            }
        }
        return null;
    }

    public static void main(String[] args) {
        int numbers[] = {2,7,11,15};
        int target = 9;
        //输出[1, 2]
        System.out.println(Arrays.toString(TwoSum.towSum(numbers, target)));
    }
}

二、两数平方和

/**
     * 判断一个数是否为2数平方和
     * Input: 5
     * Output: True
     * Explanation: 1 * 1 + 2 * 2 = 5
     * @param number
     * @return
     */
    public static boolean judgeSqrtSum(int number){
        int i = 0;
        //开平方根
        int j = (int)Math.sqrt(number);
        int result;
        while(i < j){
            result = i * i + j * j;
            if(result < number){
                i ++;
            }else if(result > number){
                j--;
            }else{
                return true;
            }
        }
        return false;
    }
查看原文

赞 0 收藏 0 评论 0

yin 发布了文章 · 2019-06-22

java算法题:最长回文串

LeetCode: 给定一个包含大写字母和小写字母的字符串,找到通过这些字母构造成的最长的回文串。在构造过程中,请注意区分大小写。比如"Aa"不能当做一个回文字符串。注 意:假设字符串的长度不会超过 1010。

思路:利用hashset,遍历字符串数组,判断字符是否在hashset中,如果在则加2,并在hashset中移除改字符,反之则放入hashset中
,最后判断count是否大于字符串长度。

代码实现:


/**
 * @author:eason
 * @desc:最长回文串(“回文串”是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串。)
 * @思路:利用hashset,遍历字符串数组,判断字符是否在hashset中,如果在则加2,并在hashset中移除改字符,反之则放入hashset中
 * ,最后判断count是否大于字符串长度
 */
public class LongestPalindromic {
    public int getLonestLength(String s){
        int count = 0;
        char[] chars = s.toCharArray();
        HashSet set = new HashSet();
        for(int i = 0;i < chars.length; i++){
            char b = chars[i];
            if(set.contains(b)){
                count += 2;
                set.remove(b);
            }else{
                set.add(b);
            }
        }
        if(count < s.length()){
            count ++;
        }
        return count;
    }

    public static void main(String[] args) {
        String s = "assdsdgggggaa";
        LongestPalindromic longestPalindromic = new LongestPalindromic();
        System.out.println(longestPalindromic.getLonestLength(s));
    }
}
查看原文

赞 0 收藏 0 评论 0

yin 发布了文章 · 2019-06-14

最长公共前缀(LCP)

最长公共前缀 LCP(longest common prefix)

Leetcode: 编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀,返回空字符串 ""。

思路:先将字符串数组排序,在比较第一个字符串与最后一个字符串的公共前缀即可
eg:["abcddd","abbddd","abccc"] -> ["abbddd","abccc","abcddd"],
只需比较第一个字符串"abbddd"与最后一个字符串"abcddd"

代码实现


/**
 * 最长公共前缀 LCP(longest common prefix)
 * Leetcode: 编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀,返回空字符串 ""。
 *
 * 思路:先将字符串数组排序,在比较第一个字符串与最后一个字符串的公共前缀即可
 * eg:["abcddd","abbddd","abccc"] -> ["abbddd","abccc","abcddd"],
 * 只需比较第一个字符串"abbddd"与最后一个字符串"abcddd"
 */
public class LCP {
    public String solution(String[] strs){
        //保存公共前缀
        StringBuffer lcpStr = new StringBuffer();
        if(strs == null){
            return lcpStr.toString();
        }
        //排序
        Arrays.sort(strs);
        String first = strs[0];
        String last = strs[strs.length - 1];
        int firstLength = first.length();
        int lastLength = last.length();
        int count = firstLength > lastLength ? lastLength : firstLength;
        for(int i = 0;i < count;i++){
            if(first.charAt(i) == last.charAt(i)){
                lcpStr.append(first.charAt(i));
            }else{
                //不一样则退出循环
                break;
            }
        }

        return lcpStr.toString();
    }

    public static void main(String[] args) {
        LCP lcp = new LCP();
        String[] strs = {"abcddd","abbddd","abccc"};
        System.out.println(lcp.solution(strs));
    }
}
查看原文

赞 0 收藏 0 评论 0

yin 发布了文章 · 2019-06-10

KMP算法java版实现

原理:http://www.ruanyifeng.com/blo...
代码


import java.util.Arrays;

public class KMP {
    private static int[] prefixTable;

    /**
     * 部分匹配表
     * @param t
     * @return
     */
    public int[] getPrefixTable(char[] t){
        int n = t.length;
        int len;//匹配位置
        prefixTable = new int[n];
        prefixTable[0] = 0;

        for(int i = 1;i < n;i++){
            len  = prefixTable[i - 1];
            while(true){
                if(t[len] == t[i]){
                    len++;
                    prefixTable[i] = len;
                    break;
                }else{
                    if(len > 0)//下一个比较位置
                        len = prefixTable[len - 1];
                    else{
                        prefixTable[i] = 0;//
                        break;
                    }
                }
            }
        }
        return prefixTable;
    }

    public int[] match(char[] s,char[] t){
        int[] result = new int[s.length];//记录所有匹配的子串
        int count = 0;
        int j = 0;//记录子串匹配位置
        for(int i = 0;i < s.length;i++){
            if(s[i] == t[j]){//相等
                if(j == t.length - 1){//子串匹配完毕,记录位置,并且j=0找下一个匹配的子串
                    result[count++] = i - t.length + 1;
                    j = 0;
                }else{//子串匹配位置加1
                    j++;
                }
            }else{
                if(j > 0){//如果子串位置>0
                    j = prefixTable[j - 1];//不匹配的话从匹配表里面找到子串新的匹配位置
                    i--;//接着比较
                }
            }
        }
        return result;
    }

    public static void main(String[] args) {
        KMP kmp= new KMP();
        char[] s = "ABCDAB ABCDABCDABDEABCDABD".toCharArray();
        char[] t = "ABCDABD".toCharArray();
        kmp.getPrefixTable(t);
        int index[] = kmp.match(s, t);
        System.out.println(Arrays.toString(index));
    }
}

输出结果

[11, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
查看原文

赞 0 收藏 0 评论 0

yin 发布了文章 · 2019-06-10

KMP算法java版实现

原理:http://www.ruanyifeng.com/blo...
代码


import java.util.Arrays;

public class KMP {
    private static int[] prefixTable;

    /**
     * 部分匹配表
     * @param t
     * @return
     */
    public int[] getPrefixTable(char[] t){
        int n = t.length;
        int len;//匹配位置
        prefixTable = new int[n];
        prefixTable[0] = 0;

        for(int i = 1;i < n;i++){
            len  = prefixTable[i - 1];
            while(true){
                if(t[len] == t[i]){
                    len++;
                    prefixTable[i] = len;
                    break;
                }else{
                    if(len > 0)//下一个比较位置
                        len = prefixTable[len - 1];
                    else{
                        prefixTable[i] = 0;//
                        break;
                    }
                }
            }
        }
        return prefixTable;
    }

    public int[] match(char[] s,char[] t){
        int[] result = new int[s.length];//记录所有匹配的子串
        int count = 0;
        int j = 0;//记录子串匹配位置
        for(int i = 0;i < s.length;i++){
            if(s[i] == t[j]){//相等
                if(j == t.length - 1){//子串匹配完毕,记录位置,并且j=0找下一个匹配的子串
                    result[count++] = i - t.length + 1;
                    j = 0;
                }else{//子串匹配位置加1
                    j++;
                }
            }else{
                if(j > 0){//如果子串位置>0
                    j = prefixTable[j - 1];//不匹配的话从匹配表里面找到子串新的匹配位置
                    i--;//接着比较
                }
            }
        }
        return result;
    }

    public static void main(String[] args) {
        KMP kmp= new KMP();
        char[] s = "ABCDAB ABCDABCDABDEABCDABD".toCharArray();
        char[] t = "ABCDABD".toCharArray();
        kmp.getPrefixTable(t);
        int index[] = kmp.match(s, t);
        System.out.println(Arrays.toString(index));
    }
}

输出结果

[11, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
查看原文

赞 0 收藏 0 评论 0

yin 发布了文章 · 2019-06-09

KMP算法java版实现

原理:http://www.ruanyifeng.com/blo...
代码


import java.util.Arrays;

public class KMP {
    private static int[] prefixTable;

    /**
     * 部分匹配表
     * @param t
     * @return
     */
    public int[] getPrefixTable(char[] t){
        int n = t.length;
        int len;//匹配位置
        prefixTable = new int[n];
        prefixTable[0] = 0;

        for(int i = 1;i < n;i++){
            len  = prefixTable[i - 1];
            while(true){
                if(t[len] == t[i]){
                    len++;
                    prefixTable[i] = len;
                    break;
                }else{
                    if(len > 0)//下一个比较位置
                        len = prefixTable[len - 1];
                    else{
                        prefixTable[i] = 0;//
                        break;
                    }
                }
            }
        }
        return prefixTable;
    }

    public int[] match(char[] s,char[] t){
        int[] result = new int[s.length];//记录所有匹配的子串
        int count = 0;
        int j = 0;//记录子串匹配位置
        for(int i = 0;i < s.length;i++){
            if(s[i] == t[j]){//相等
                if(j == t.length - 1){//子串匹配完毕,记录位置,并且j=0找下一个匹配的子串
                    result[count++] = i - t.length + 1;
                    j = 0;
                }else{//子串匹配位置加1
                    j++;
                }
            }else{
                if(j > 0){//如果子串位置>0
                    j = prefixTable[j - 1];//不匹配的话从匹配表里面找到子串新的匹配位置
                    i--;//接着比较
                }
            }
        }
        return result;
    }

    public static void main(String[] args) {
        KMP kmp= new KMP();
        char[] s = "ABCDAB ABCDABCDABDEABCDABD".toCharArray();
        char[] t = "ABCDABD".toCharArray();
        kmp.getPrefixTable(t);
        int index[] = kmp.match(s, t);
        System.out.println(Arrays.toString(index));
    }
}

输出结果

[11, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
查看原文

赞 0 收藏 0 评论 0

yin 关注了专栏 · 2019-06-06

搜云库技术团队

专注于开发技术的研究与知识分享

关注 387

yin 赞了文章 · 2019-03-11

MySQL 数据库设计总结

本文由云+社区发表

作者:漆洪凯

规则1:一般情况可以选择MyISAM存储引擎,如果需要事务支持必须使用InnoDB存储引擎。

注意:MyISAM存储引擎 B-tree索引有一个很大的限制:参与一个索引的所有字段的长度之和不能超过1000字节。另外MyISAM数据和索引是分开,而InnoDB的数据存储是按聚簇(cluster)索引有序排列的,主键是默认的聚簇(cluster)索引,因此MyISAM虽然在一般情况下,查询性能比InnoDB高,但InnoDB的以主键为条件的查询性能是非常高的。

规则2:命名规则。

  1. 数据库和表名应尽可能和所服务的业务模块名一致
  2. 服务与同一个子模块的一类表应尽量以子模块名(或部分单词)为前缀或后缀
  3. 表名应尽量包含与所存放数据对应的单词
  4. 字段名称也应尽量保持和实际数据相对应
  5. 联合索引名称应尽量包含所有索引键字段名或缩写,且各字段名在索引名中的顺序应与索引键在索引中的索引顺序一致,并尽量包含一个类似idx的前缀或后缀,以表明期对象类型是索引。
  6. 约束等其他对象也应该尽可能包含所属表或其他对象的名称,以表明各自的关系

规则3:数据库字段类型定义

  1. 经常需要计算和排序等消耗CPU的字段,应该尽量选择更为迅速的字段,如用TIMESTAMP(4个字节,最小值1970-01-01 00:00:00)代替Datetime(8个字节,最小值1001-01-01 00:00:00),通过整型替代浮点型和字符型
  2. 变长字段使用varchar,不要使用char
  3. 对于二进制多媒体数据,流水队列数据(如日志),超大文本数据不要放在数据库字段中

规则4:业务逻辑执行过程必须读到的表中必须要有初始的值。避免业务读出为负或无穷大的值导致程序失败

规则5:并不需要一定遵守范式理论,适度的冗余,让Query尽量减少Join

规则6:访问频率较低的大字段拆分出数据表。有些大字段占用空间多,访问频率较其他字段明显要少很多,这种情况进行拆分,频繁的查询中就不需要读取大字段,造成IO资源的浪费。

规则7:大表可以考虑水平拆分。大表影响查询效率,根据业务特性有很多拆分方式,像根据时间递增的数据,可以根据时间来分。以id划分的数据,可根据id%数据库个数的方式来拆分。

一.数据库索引

规则8:业务需要的相关索引是根据实际的设计所构造sql语句的where条件来确定的,业务不需要的不要建索引,不允许在联合索引(或主键)中存在多于的字段。特别是该字段根本不会在条件语句中出现。

规则9:唯一确定一条记录的一个字段或多个字段要建立主键或者唯一索引,不能唯一确定一条记录,为了提高查询效率建普通索引

规则10:业务使用的表,有些记录数很少,甚至只有一条记录,为了约束的需要,也要建立索引或者设置主键。

规则11:对于取值不能重复,经常作为查询条件的字段,应该建唯一索引(主键默认唯一索引),并且将查询条件中该字段的条件置于第一个位置。没有必要再建立与该字段有关的联合索引。

规则12:对于经常查询的字段,其值不唯一,也应该考虑建立普通索引,查询语句中该字段条件置于第一个位置,对联合索引处理的方法同样。

规则13:业务通过不唯一索引访问数据时,需要考虑通过该索引值返回的记录稠密度,原则上可能的稠密度最大不能高于0.2,如果稠密度太大,则不合适建立索引了。

当通过这个索引查找得到的数据量占到表内所有数据的20%以上时,则需要考虑建立该索引的代价,同时由于索引扫描产生的都是随机I/O,生其效率比全表顺序扫描的顺序I/O低很多。数据库系统优化query的时候有可能不会用到这个索引。

规则14:需要联合索引(或联合主键)的数据库要注意索引的顺序。SQL语句中的匹配条件也要跟索引的顺序保持一致。

注意:索引的顺势不正确也可能导致严重的后果。

规则15:表中的多个字段查询作为查询条件,不含有其他索引,并且字段联合值不重复,可以在这多个字段上建唯一的联合索引,假设索引字段为 (a1,a2,...an),则查询条件(a1 op val1,a2 op val2,...am op valm)m<=n,可以用到索引,查询条件中字段的位置与索引中的字段位置是一致的。

规则16:联合索引的建立原则(以下均假设在数据库表的字段a,b,c上建立联合索引(a,b,c))

  1. 联合索引中的字段应尽量满足过滤数据从多到少的顺序,也就是说差异最大的字段应该房子第一个字段
  2. 建立索引尽量与SQL语句的条件顺序一致,使SQL语句尽量以整个索引为条件,尽量避免以索引的一部分(特别是首个条件与索引的首个字段不一致时)作为查询的条件
  3. Where a=1,where a>=12 and a<15,where a=1 and b<5 ,where a=1 and b=7 and c>=40为条件可以用到此联合索引;而这些语句where b=10,where c=221,where b>=12 and c=2则无法用到这个联合索引。
  4. 当需要查询的数据库字段全部在索引中体现时,数据库可以直接查询索引得到查询信息无须对整个表进行扫描(这就是所谓的key-only),能大大的提高查询效率。 当a,ab,abc与其他表字段关联查询时可以用到索引
  5. 当a,ab,abc顺序而不是b,c,bc,ac为顺序执行Order by或者group不要时可以用到索引
  6. 以下情况时,进行表扫描然后排序可能比使用联合索引更加有效 a.表已经按照索引组织好了 b.被查询的数据站所有数据的很多比例。

规则17:重要业务访问数据表时。但不能通过索引访问数据时,应该确保顺序访问的记录数目是有限的,原则上不得多于10.

二.Query语句与应用系统优化

规则18:合理构造Query语句

  1. Insert语句中,根据测试,批量一次插入1000条时效率最高,多于1000条时,要拆分,多次进行同样的插入,应该合并批量进行。注意query语句的长度要小于mysqld的参数 max_allowed_packet
  2. 查询条件中各种逻辑操作符性能顺序是and,or,in,因此在查询条件中应该尽量避免使用在大集合中使用in
  3. 永远用小结果集驱动大记录集,因为在mysql中,只有Nested Join一种Join方式,就是说mysql的join是通过嵌套循环来实现的。通过小结果集驱动大记录集这个原则来减少嵌套循环的循环次数,以减少IO总量及CPU运算次数
  4. 尽量优化Nested Join内层循环。
  5. 只取需要的columns,尽量不要使用select *
  6. 仅仅使用最有效的过滤字段,where 字句中的过滤条件少为好
  7. 尽量避免复杂的Join和子查询 Mysql在并发这块做得并不是太好,当并发量太高的时候,整体性能会急剧下降,这主要与Mysql内部资源的争用锁定控制有关,MyIsam用表锁,InnoDB好一些用行锁。

规则19:应用系统的优化

  1. 合理使用cache,对于变化较少的部分活跃数据通过应用层的cache缓存到内存中,对性能的提升是成数量级的。
  2. 对重复执行相同的query进行合并,减少IO次数。
  3. 事务相关性最小原则

此文已由腾讯云+社区在各渠道发布

获取更多新鲜技术干货,可以关注我们腾讯云技术社区-云加社区官方号及知乎机构号

查看原文

赞 44 收藏 35 评论 0

认证与成就

  • 获得 13 次点赞
  • 获得 1 枚徽章 获得 0 枚金徽章, 获得 0 枚银徽章, 获得 1 枚铜徽章

擅长技能
编辑

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 2014-09-01
个人主页被 630 人浏览