MySQL学习笔记(三)索引

索引
简介

索引是一个单独的、存储 在磁盘上的数据库结构,他们包含着对数据表里所有记录的引用指针。使用索引用于快速找出在某个或多个列有一特定值的行,所有MySQL列类型都可以被索引,对相关列使用索引是提高查询操作速度的最佳途径。

索引的优点
  1. 可以大大加快数据的查询速度。
  2. 在实现数据的参考完整性方面,可以加速表和表之间的连接。
  3. 在使用分组和排序子句进行数据查询时,也可以显著减少查询中分组和排序的时间。
  4. 主键索引的叶子结点存储了整一行的内容(聚簇索引),使用主键可以快速获取到整行的数据。
索引的缺点
  1. 创建索引和维护索引要耗费时间,并且随着数据量的增加所耗费的时间也会增加。
  2. 索引需要占磁盘空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果有大量的索引,索引文件可能比数据文件更快达到最大文件尺寸。
  3. 当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度。
索引的设计原则
  1. 索引并非越多越好。过多的索引会占用大量内存空间,而且会影响增删改的性能。
  2. 避免对经常更新的表建立过多的索引,并且索引中的列要尽可能少。
  3. 数据量的表最好不要建立索引,由于数据较少,查询花费的时间可能比遍历索引的时间还要短。
  4. 在条件表达式中经常用到的不同值较多的列上建立索引。如学生表中的‘性别’列,只有“男”,“女”两个值,就无需建立索引。
  5. 在频繁进行排序和分组的列上建立索引,如果待排序的列有多个,可以在这些列上建立组合索引。
  6. 对于字符串类型的字段进行索引,如果可能应该指定一个前缀长度。如果有一个char(255)的列 在前10个或前30个字符内,多数值是唯一的,则不需要对整个列建立索引。短索引不仅可以提高查询速度而且可以节省磁盘空间,减少I/O操作。
索引优化

慢查询日志:会记录所有执行时间超过long_query_time的所有查询或不使用索引的查询,所以可以根据慢查询日志进行对应sql语句优化。

使用覆盖索引:覆盖索引即查询的所有列都有索引,使用覆盖索引可以减少大量回表操作,也会可以进行范围查找减少磁盘IO。
(回表操作:先索引扫描,再通过主键去取索引中未能提供的数据,即为回表)
回表操作解释

索引顺序:将选择性高的索引放在前面,可以过滤大多数索引。如果已有(a,b)索引 就不需要再维护一个a索引。

定期清除过时索引:维护索引需要耗费系统大量资源,尤其是当表中数据比较多得时候。

尽量拓展索引而不是新建索引。

不会使用索引的情况

  1. 使用LIKE 关键字进行查询的查询语句中,如果匹配字符串的第一个字符为“%”,索引不会起作用。只有“%”不在第一个位置,索引才会起作用。
  2. 使用多列索引时,只有在查询条件中使用了这些字段的第一个字段时,索引才会被使用。最左匹配原则。
    ex:CREATE INDEX index_id_price ON fruits(f_id,f_price);
    SELECT * FROM fruits WHERE f_id=‘12’;
    此时会使用索引
    SELECT * FROM fruits WHERE f_price=5.2;
    此时不会使用索引
  3. 索引列不能是表达式的一部分,也不能是函数的参数。
    ex: select * from table where id-1>4;
    此时id是表达式的一部分 就不会使用索引。
以下是一个简单的人日记本程序的代码示例,可以在安卓手机上运行: 1. MainActivity.java ```java import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.fragment.app.DialogFragment; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.Button; import android.widget.CalendarView; import android.widget.EditText; import android.widget.Toast; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.List; public class MainActivity extends AppCompatActivity implements DatePickerFragment.OnDateSetListener { private RecyclerView recyclerView; private RecyclerView.Adapter adapter; private RecyclerView.LayoutManager layoutManager; private List<Diary> diaryList; private Button dateButton; private EditText contentEditText; private String currentDate; private DatabaseHelper databaseHelper; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); recyclerView = findViewById(R.id.recycler_view); recyclerView.setHasFixedSize(true); layoutManager = new LinearLayoutManager(this); recyclerView.setLayoutManager(layoutManager); diaryList = new ArrayList<>(); adapter = new DiaryAdapter(diaryList); recyclerView.setAdapter(adapter); dateButton = findViewById(R.id.date_button); contentEditText = findViewById(R.id.content_edit_text); Calendar calendar = Calendar.getInstance(); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); currentDate = dateFormat.format(calendar.getTime()); dateButton.setText(currentDate); databaseHelper = new DatabaseHelper(this); updateDiaryList(); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(@NonNull MenuItem item) { if (item.getItemId() == R.id.action_add) { showDatePickerDialog(); return true; } return super.onOptionsItemSelected(item); } public void onSaveButtonClick(View view) { String content = contentEditText.getText().toString().trim(); if (content.isEmpty()) { Toast.makeText(this, "请填写日记内容", Toast.LENGTH_SHORT).show(); return; } Diary diary = new Diary(currentDate, content); databaseHelper.addDiary(diary); updateDiaryList(); contentEditText.setText(""); } private void updateDiaryList() { diaryList.clear(); diaryList.addAll(databaseHelper.getDiaryList(currentDate)); adapter.notifyDataSetChanged(); } private void showDatePickerDialog() { DialogFragment newFragment = new DatePickerFragment(); newFragment.show(getSupportFragmentManager(), "datePicker"); } @Override public void onDateSet(int year, int month, int day) { currentDate = String.format("%04d-%02d-%02d", year, month + 1, day); dateButton.setText(currentDate); updateDiaryList(); } } ``` 2. activity_main.xml ```xml <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <androidx.recyclerview.widget.RecyclerView android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@+id/input_layout" android:padding="16dp" /> <LinearLayout android:id="@+id/input_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:orientation="vertical" android:padding="16dp"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <Button android:id="@+id/date_button" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="日期" /> <Button android:id="@+id/save_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="保存" android:onClick="onSaveButtonClick" /> </LinearLayout> <EditText android:id="@+id/content_edit_text" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="日记内容" /> </LinearLayout> </RelativeLayout> ``` 3. Diary.java ```java public class Diary { private String date; private String content; public Diary(String date, String content) { this.date = date; this.content = content; } public String getDate() { return date; } public String getContent() { return content; } } ``` 4. DiaryAdapter.java ```java import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import java.util.List; public class DiaryAdapter extends RecyclerView.Adapter<DiaryAdapter.DiaryViewHolder> { private List<Diary> diaryList; public DiaryAdapter(List<Diary> diaryList) { this.diaryList = diaryList; } @NonNull @Override public DiaryViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.diary_item, parent, false); return new DiaryViewHolder(view); } @Override public void onBindViewHolder(@NonNull DiaryViewHolder holder, int position) { Diary diary = diaryList.get(position); holder.dateTextView.setText(diary.getDate()); holder.contentTextView.setText(diary.getContent()); } @Override public int getItemCount() { return diaryList.size(); } public static class DiaryViewHolder extends RecyclerView.ViewHolder { public TextView dateTextView; public TextView contentTextView; public DiaryViewHolder(@NonNull View itemView) { super(itemView); dateTextView = itemView.findViewById(R.id.date_text_view); contentTextView = itemView.findViewById(R.id.content_text_view); } } } ``` 5. diary_item.xml ```xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:id="@+id/date_text_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:textAppearance="?android:textAppearanceMedium" android:textColor="?android:attr/textColorPrimary" /> <TextView android:id="@+id/content_text_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:textAppearance="?android:textAppearanceMedium" android:textColor="?android:attr/textColorSecondary" /> </LinearLayout> ``` 6. DatePickerFragment.java ```java import android.app.DatePickerDialog; import android.app.Dialog; import android.os.Bundle; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.DialogFragment; import java.util.Calendar; public class DatePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener { private OnDateSetListener listener; public interface OnDateSetListener { void onDateSet(int year, int month, int day); } @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); try { listener = (OnDateSetListener) getActivity(); } catch (ClassCastException e) { throw new ClassCastException(getActivity().toString() + " must implement OnDateSetListener"); } } @NonNull @Override public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { Calendar calendar = Calendar.getInstance(); int year = calendar.get(Calendar.YEAR); int month = calendar.get(Calendar.MONTH); int day = calendar.get(Calendar.DAY_OF_MONTH); return new DatePickerDialog(getActivity(), this, year, month, day); } @Override public void onDateSet(android.widget.DatePicker view, int year, int month, int dayOfMonth) { listener.onDateSet(year, month, dayOfMonth); } } ``` 这个程序包含一个日记列表和一个日历视图,可以添加新的日记并查看指定日期的日记列表。日记数据存储在SQLite数据库中。在添加新日记时,用户可以选择日期,也可以使用当前日期。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值