我有一张如下表格,
Field Type Null Key Default Extra
id bigint(11) NO PRI NULL auto_increment
deviceId bigint(11) NO MUL NULL
value double NO NULL
time timestamp YES MUL 0000-00-00 00:00:00
它有超过200万行。当我跑select * from tableName;
时需要超过15分钟。
当我运行select value,time from sensor_value where time > '2017-05-21 04:47:48' and deviceId>=812;
加载时需要超过45秒。
注意: 512有超过92514行。 即使我为下面的列添加了索引,
ALTER TABLE `sensor_value`
ADD INDEX `IDX_FIELDS1_2` (`time`, `deviceId`) ;
如何快速选择查询?(在1秒内加载)我的索引编写错误吗?
答案 0 :(得分:2)
只有4列?听起来你的RAM很少,或innodb_buffer_pool_size
设置得太低。因此,您严重受I / O限制和/或交换。
WHERE time > '2017-05-21 04:47:48'
AND deviceId >= 812
是两个范围。没有彻底的方法来优化它。这些都有帮助。如果你有两者,优化器可能选择更好的一个:
INDEX(time)
INDEX(deviceId)
在InnoDB中使用“辅助”索引时,查询首先查看索引BTree;当那里有匹配时,它必须在“数据”BTree中查找(使用PRIMARY KEY
进行查找)。
您在尝试INDEX(time, deviceId)
时看到的一些异常时间是因为过滤不必经常覆盖到数据中。
您是否将id
用于除唯一性之外的任何其他内容?对装置是否是&时间独特?如果答案为“否”和“是”,则取消id
并更改为PRIMARY KEY(deviceId, time)
。或者你可以交换这两列。您还有其他疑问吗?
摆脱id
会缩小表格,从而减少I / O.
答案 1 :(得分:1)
通常使用组合索引时,必须在第一列上使用相等运算符,然后可以在第二列上使用范围条件。因此,我建议您更改索引中的列顺序,如下所示:
ublic class TheMedicalResourceManagementSystem
{
JFrame jf;
JPanel jp;
JButton b;
JTextField t;
JTextField t2;
public static void main(String[] args)
{
TheMedicalResourceManagementSystem cc = new TheMedicalResourceManagementSystem();
// SwingUtilities.invokeLater(() -> new GUI("The Medical Resource Management System").setVisible(true));
}
public TheMedicalResourceManagementSystem()
{
jf = new JFrame("Frame");
jp = new JPanel();
jp.setLayout(new FlowLayout());
jf.add(jp);
t = new JTextField(15);
jp.add(t);
t2 = new JTextField(15);
jp.add(t);
jp.add(t2);
b= new JButton("Login");
jp.add(b);
jf.setSize(200,200);
jf.setVisible(true);
String username = t.getText();
String password = t2.getText();
b.addActionListener((ActionEvent e) -> {
if(username.equals("admin") && password.equals("password"))
{
SwingUtilities.invokeLater(() -> new GUI("Medical Remote Management System").setVisible(true));
}
else
{
JOptionPane.showMessageDialog( null, "Incorrect username or password , Please try again");
}});
}
}
然后更改为ALTER TABLE `sensor_value`
ADD INDEX `IDX_FIELDS1_2` (`deviceId`, `time`) ;
使用等号(使用deviceId
而非deviceId=812
):
deviceId>=812
我希望它可以提供帮助。
对于Mysql而言,200万条记录并不多,如果做正确的事情,10亿条记录的结果不到1秒是正常的。