Php,Mysql - 如何在我的情况下使用大数据


Php, Mysql - How to working with big data in my case

>我有两个包含大数据的表格,示例中 http://www.sqlfiddle.com/#!2/ee61b/3

表 1 类似

CREATE TABLE `t1`(
  `id` int(4) ,
  `name` varchar(40),
  `signal` int(4)
)
;
INSERT INTO `t1`
(`id`, `name`, `signal`)
VALUES
    (1, 'a', 1),
    (2, 'b', 1),
    (3, 'c', 0),
    (4, 'd', 0)
;

表 2 喜欢

CREATE TABLE `t2`(
  `uid` int(4),
  `type` int(4),
  `usignal` int(4)
)
;
INSERT INTO `t2`
(`uid`, `type`, `usignal`)
VALUES
    (3, 1, 1),
    (1, 2, 1),
    (4, 1, 0),
    (2, 2, 0)
;

现在我尝试让所有记录都有条件的喜欢
1. 表 1 中的所有记录都有 signal = 1
2. OR(+) 表 1 中的所有记录都有 id in (t2从中选择 UID,其中 t2.type = 1 和 t2.usignal = 1)

我这样做就像

SELECT * FROM `t1` AS g1
WHERE g1.signal = 1
UNION 
SELECT * FROM  `t1` AS g1
WHERE g1.id
IN (
    SELECT uid
    FROM  `t2` AS g2
    WHERE g2.usignal = 1 AND g2.type = 1
)

但我必须对此做一些条件(mybe join,...),我这样做就像

SELECT * FROM `t1` AS g1
WHERE g1.signal = 1
UNION 
SELECT * FROM  `t1` AS g1
WHERE g1.id
IN (
    SELECT uid
    FROM  `t2` AS g2
    WHERE g2.usignal = 1 AND g2.type = 1
)
/*dynamic other join query here */
and id>=1 /*dynamic conditional query here*/
order by id desc limit 0,20

如果数据很小,则效果很好,但是我的数据更大,并且在执行时失败

我该怎么做谢谢

编辑:
我的 sql 呢?这是否使执行缓慢并使其超时?

编辑02:
我使用phpmyadmin并单击索引以t1(id, signal)t2(type, unsignal)
并且我在两个表示例中都添加了id主键http://www.sqlfiddle.com/#!2/d88a9/1
但实际上我的表格大约有 10 列。我使用左连接,但这仍然是超时:(

尝试摆脱您的子查询并使用 join ,我还从查询中删除了联合,为此我将条件括在大括号中以满足您的联合需求

SELECT g1.* FROM `t1` AS g1
left join `t2` AS g2 on (g1.id=g2.uid)
WHERE (
(g2.usignal = 1 AND g2.type = 1 )
 OR g1.signal = 1      
  )
order by id desc limit 0,20

还要确保列上有适当的索引

看到这个小提琴

您收到什么错误,以便我们可以回答您的问题..您可以从PHP ini设置最大执行时间,如下所示: ini_set('max_execution_time', 300); 您的任务将工作 300 秒而不是 30 秒 .

您是否尝试过加入而不是嵌套选择(这不会很快)?

SELECT g1.* FROM `t1` AS g1
LEFT JOIN `t2` AS g2 ON g2.uid = g1.id 
WHERE g1.signal = 1
 OR (g2.usignal = 1 AND g2.type = 1)
/*dynamic other join query here */
and id>=1 /*dynamic conditional query here*/
order by id desc limit 0,20

在您的 SQL-Fiddle http://www.sqlfiddle.com/#!2/ee61b/3 下方的绿色导航栏中有一个选项:"+ 查看执行计划"。 您还可以通过在查询前面添加"解释"来获取此信息。

在您的情况下,结果如下所示:

+------+--------------+-------------+--------+---------------+--------------+---------+------+------+-------------+
| id   | select_type  | table       | type   | possible_keys | key          | key_len | ref  | rows | Extra       |
+------+--------------+-------------+--------+---------------+--------------+---------+------+------+-------------+
|    1 | PRIMARY      | g1          | ALL    | NULL          | NULL         | NULL    | NULL |    4 | Using where |
|    2 | UNION        | g1          | ALL    | NULL          | NULL         | NULL    | NULL |    4 |             |
|    2 | UNION        | <subquery3> | eq_ref | distinct_key  | distinct_key | 4       | func |    1 |             |
|    3 | MATERIALIZED | g2          | ALL    | NULL          | NULL         | NULL    | NULL |    4 | Using where |
| NULL | UNION RESULT | <union1,2>  | ALL    | NULL          | NULL         | NULL    | NULL | NULL |             |
+------+--------------+-------------+--------+---------------+--------------+---------+------+------+-------------+

查看"possible_keys"列:到处都有 NULL。这很糟糕,这意味着数据库必须按顺序搜索您的数据才能找到某些内容。

如果将正确的主键和索引添加到数据库中,则每次搜索都将使用像树这样的智能数据结构完成,并且速度会快得多,尤其是对于大日期:

+------+--------------+------------+--------+-----------------+---------+---------+-------------+------+-------------+
| id   | select_type  | table      | type   | possible_keys   | key     | key_len | ref         | rows | Extra       |
+------+--------------+------------+--------+-----------------+---------+---------+-------------+------+-------------+
|    1 | PRIMARY      | g1         | ref    | signal          | signal  | 5       | const       |    2 |             |
|    2 | UNION        | g2         | ref    | PRIMARY,usignal | usignal | 5       | const       |    2 | Using where |
|    2 | UNION        | g1         | eq_ref | PRIMARY         | PRIMARY | 4       | test.g2.uid |    1 |             |
| NULL | UNION RESULT | <union1,2> | ALL    | NULL            | NULL    | NULL    | NULL        | NULL |             |
+------+--------------+------------+--------+-----------------+---------+---------+-------------+------+-------------+

所以:阅读主键和索引,并将这些知识应用到你的例子中。

你有什么索引吗?确保您创建了正确的。

对于t1来说,你似乎需要一个(idsignal)元组的索引。对于t2,你需要在(usignaltype)元组上有一个索引。

如果您还没有,您可以通过以下方式添加它们(根据您没有的创建表):

create index 'id_signal_index' on t1 (`id`, `signal`);
create index 'id_usignal_index' on t2 (`usignal`, `type`);

通常,最好在像 t1 这样的表中使用主键来id具有自动增量。

此外,将内部查询转换为左联接查询,这在其他答案中有说明。

索引

t1 signalt2usignalutype)。

还要定义主键。

相关文章: