我有一张包含 1.5 亿行数据的 MySQL 表。下面是其数据结构。
以下是它的一些数据。
现在,我使用 PHP My Admin 运行以下命令。
SELECT `iwords` FROM `wordstable` WHERE `iwebs` = "a1"
它表示运行查询所用时间不到一秒钟。以下是证明。
但实际上,这花了大约 1 分钟的时间才显示数据!!
因此我运行了 Java 代码来查看时间。如下所示。
public void select(String str)
{
try {
long startTime = System.currentTimeMillis();
Statement s = con.createStatement();
ResultSet executeQuery = s.executeQuery("SELECT `iwords` FROM `wordstable` WHERE `iwebs` = \"a1\" ");
int r=0;
long endTime = System.currentTimeMillis();
System.out.println("Time took by Database: "+(endTime-startTime));
while(executeQuery.next())
{
r++;
}
System.out.println("Number of rows: "+String.valueOf(r));
} catch (SQLException ex) {
ex.printStackTrace();
}
}
此代码打印的时间为 88779 毫秒,即 88.779 秒!
这是一个非常大的问题,我有一个单词数组需要搜索,如果搜索一个“单个”单词需要 88 秒,那么这将毫无用处!
下面是我的一些高级表格详细信息。
以下是有关服务器的详细信息
所以我的问题是,MySQL 真的能完成这个任务吗?根据 MySQL 的说法,执行查询所用的时间不到一秒,但实际上为什么会花这么多时间?我未来的数据库将比这更大,有数十亿条记录。我至少需要在 2-3 秒内完成此操作!
更新
根据 SO 成员的要求,我运行了以下命令并发布了他们的结果。
输入 解释从 wordstable 中选择 iwords,其中 iwebs = 'a1';
结果
输入
SET profiling=1;
SELECT iwords FROM wordstable WHERE iwebs = 'a1';
SHOW profile;
输出
最后,我使用远程桌面访问该服务器,但所有代码和所有内容都在服务器内部运行。
答案1
该表上有索引吗?
请发布输出:
EXPLAIN SELECT iwords FROM wordstable WHERE iwebs = 'a1';
然后发布以下命令组的输出:
SET profiling=1;
SELECT iwords FROM wordstable WHERE iwebs = 'a1';
SHOW profile;
这将告诉您 MySQL 在哪里挂起,然后您至少知道从哪里开始。
更新:
看了你更新的问题后,我不知道为什么 MySQL 找不到合适的键来运行你的查询。'iwebs' 可以包含的值集有多大?你的持续时间显然是从缓存中获取的。你应该通过以下方式重置 MySQL 查询缓存
RESET QUERY CACHE;
如果你有重新加载权限,否则你应该使用
FLUSH QUERY CACHE;
如果您也无法执行此命令,则必须重新启动 MySQL 服务器实例。
正如 Nebu 所说,使用 SQL_NO_CACHE 标志重新运行您的命令,以确保它不会妨碍。
所以:
EXPLAIN SELECT SQL_NO_CACHE iwords FROM wordstable WHERE iwebs = 'a1';
SET profiling=1;
SELECT SQL_NO_CACHE iwords FROM wordstable WHERE iwebs = 'a1';
SHOW profile;
答案2
认为查询已被缓存。尝试
SELECT SQL_NO_CACHE iwords FROM wordstable WHERE iwebs = 'a1';
这将更好地指示执行查询需要多长时间。还要确保 iwebs 已编入索引。最后,为了真正加快查询速度,请将表存储在内存中:
创建表ii_table
(....)引擎=内存默认字符集=utf8
将表存储在内存中确实有一些影响。例如,每次 mysql 服务器停止时,表信息就会消失。对于这种情况,我个人会创建两个表。一个用于执行查询的内存表和一个磁盘表。当 mysql 启动时,它会将磁盘表加载到内存中。