分类 我爱编程 下的文章

Elasticsearch笔记:聚合查询

聚合框架有助于根据搜索查询提供聚合数据。聚合查询是数据库中重要的功能特性,ES作为搜索引擎兼数据库,同样提供了强大的聚合分析能力。它基于查询条件来对数据进行分桶、计算的方法。有点类似于 SQL 中的 group by 再加一些函数方法的操作。聚合可以嵌套,由此可以组成复杂的操作(Bucketing聚合可以包含sub-aggregation)。


聚合计算的值可以取字段的值,也可是脚本计算的结果。查询请求体中以aggregations节点的语法定义: 


"aggregations" : {                        //也可简写为 aggs

    "<aggregation_name>" : {      //聚合的名字

        "<aggregation_type>" : {     //聚合的类型

            <aggregation_body>      //聚合体:对哪些字段进行聚合

        }

        [,"meta" : {  [<meta_data_body>] } ]?                 //元

        [,"aggregations" : { [<sub_aggregation>]+ } ]?   //在聚合里面在定义子聚合

    }

    [,"<aggregation_name_2>" : { ... } ]*                      //聚合的名字

}



————————————————

版权声明:本文为CSDN博主「布道」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/alex_xfboy/article/details/86100037


ORACLE几种分页查询SQL语句

ORACLE几种分页查询SQL语句

一、效率高的写法

1.无ORDER BY排序的写法。(效率最高)
(经过测试,此方法成本最低,只嵌套一层,速度最快!即使查询的数据量再大,也几乎不受影响,速度依然!)

复制代码

SELECT *

  FROM (SELECT ROWNUM AS rowno, t.*

          FROM emp t         WHERE hire_date BETWEEN TO_DATE ('20060501', 'yyyymmdd')                             AND TO_DATE ('20060731', 'yyyymmdd')           AND ROWNUM <= 20) table_alias WHERE table_alias.rowno >= 10;

复制代码

2.有ORDER BY排序的写法。(效率较高)
(经过测试,此方法随着查询范围的扩大,速度也会越来越慢)

复制代码

SELECT *

  FROM (SELECT tt.*, ROWNUM AS rowno          FROM (  SELECT t.*

                    FROM emp t                   WHERE hire_date BETWEEN TO_DATE ('20060501', 'yyyymmdd')                                       AND TO_DATE ('20060731', 'yyyymmdd')                ORDER BY create_time DESC, emp_no) tt         WHERE ROWNUM <= 20) table_alias WHERE table_alias.rowno >= 10;

复制代码

二、效率垃圾但又似乎很常用的分页写法

复制代码

SELECT *

  FROM (SELECT ROWNUM AS rowno, t.*

          FROM k_task t         WHERE flight_date BETWEEN TO_DATE ('20060501', 'yyyymmdd')                               AND TO_DATE ('20060731', 'yyyymmdd')) table_alias WHERE table_alias.rowno <= 20 AND table_alias.rowno >= 10;--TABLE_ALIAS.ROWNO  between 10 and 100;

复制代码



macOS Mojave 安装 PHP OCI8/PDO_OCI

前面和网上说的都差不多(和 Linux 编译安装类似),去 Oracle 下载如下的安装包(可以选择版本,我这里选择的是 12.2)

  • instantclient-basic-macos.x64-12.2.0.1.0-2.zip

  • instantclient-sdk-macos.x64-12.2.0.1.0-2.zip

  • instantclient-sqlplus-macos.x64-12.2.0.1.0-2.zip

由于 macOS 开启了 SIP 基本上所有的操作都需要在 /usr/local/ 目录下进行

解压:

sudo unzip instantclient-basic-macos.x64-12.2.0.1.0-2.zip -d /usr/local/
sudo unzip instantclient-sdk-macos.x64-12.2.0.1.0-2.zip -d /usr/local/
sudo unzip instantclient-sqlplus-macos.x64-12.2.0.1.0-2.zip -d /usr/local/# 设置环境变量vim ~/.bash_profileexport LD_LIBRARY_PATH="/usr/local/instantclient_12_2"
默认都会解压到 /usr/local/instantclient_12_2 目录下

网上的资料都是表示这个时候直接使用 pecl install oci8,而实际上 macOS 默认并没有安装这个命令;这个时候也没有安装 Homebrew

所以我先安装 Pear,先是参考这篇文章

curl -O https://pear.php.net/go-pear.phar
php -d detect_unicode=0 go-pear.phar

以下摘录于官方文档

You're now ready to configure PEAR for installation.

First you need to change the Installation Base.

  1. So type 1, and then press Enter.

  2. Enter /usr/local/pear

  3. Press Enter.

Then, you will need to change the Binaries directory.

  1. Type 4, and then press Enter.

  2. Enter /usr/local/bin

  3. Press Enter.

到这里基本上可以使用 pecl 了,执行如下命令

sudo pecl install oci8

运行安装表示还是会报错缺失 PHP_AUTOCONF 未配置; 查询之后得知需要安装 autoconf 并且不建议直接安装(说是太多依赖,我没有验证),应该使用 Homebrew

安装 Homebrew

ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

由于众所周知的原因, 慢如蜗牛; 于是查询解决方案, 参考如下

  • macOS系统下安装Homebrew

  • 实际上有些地方是不一致的,比如文中提到的没有的变量再接下来的 homebrew-core 的 clone 中无法生效,导致这个仓库会非常慢,暂时也没有得到什么解决方案

  • 按照完成之后再将几个地址换成国内的镜像,如文中所述

  • 之后直接运行命令 brew install autoconf

默认在命令行中 brew 是没有提示的,那么可以参考官方文档 https://docs.brew.sh/Shell-Completion 进行设置,开启提示

然后再次运行,应该就可以安装了

sudo pecl install oci8

然后重启 Apache sudo apachectl restart,通过访问有 phpinfo(); 的页面去确认。

这个时候一般 OCI8 是安装好了,可是项目需要的是 PDO_OCI,使用老的办法炮制 sudo pecl install pdo_oci 发现安装不了,说没有这个库,或者是要求 PHP 版本小于 6

这个时候只能通过编译源码中的扩展来实现(这些步骤和在 Ubuntu 下编译就是一模一样的了)

  1. 查看 PHP 版本 php -v 得到版本 7.1.23 那么去 PHP 官网下载对应版本的源码 https://www.php.net/releases/

  2. 解压到方便操作的地方,比如我放在桌面

  3. 进入目录后进入 ext/pdo_oci/

  4. 将命令行切换到这个目录,然后运行 phpize

./configure --with-pdo-oci=instantclient,/usr/local/instantclient_12_2,12.2
make# 这里会报安装失败,原因是无法创建目录由于 SIP 的原因sudo make install

由于 SIP 的原因到这一步就无法再继续了,只能够关闭 SIP,而关闭 SIP 需要重启按住 cmd + R 然后再菜单栏中打开终端

# 关闭 SIPcsrutil disable# 重启reboot

然后进入系统之后再次编译安装即可成功(可以选择是否恢复 SIP,重启并设置 csrutil enable

最后配置 php.ini

extension = pdo_oci.so

再重启 Apache sudo apachectl restart,再次访问项目,已经可以正常打开

到这里目的已经达成了


php rabbitMq异常消息重新入队或垃圾处理

主要解决一些异常消息导致队列堵塞,正常消息无法被进行消费。


下面为PHP实例代码:

/**
 * @param $queueName
 * @return mixed
 * @author: pengjch 2019-10-10 16:45
 */
public function rabbitMqMsgProcess($queueName){
    /**@var $rabbitMq RabbitMq**/
    $rabbitMq = Yii::app()->rabbitmq->getInstance();
    $exchangeName = $queueName."_exchange";
    $routingKey = $queueName."_routingKey";
    $rabbitMq->setExchange($exchangeName, AMQP_EX_TYPE_TOPIC);
    $rabbitMq->setQueue( $queueName, $routingKey);
    return $rabbitMq->run( array( $this, "rabbitMqMsgHandle" ), false );
}
/**
 * @param $envelope
 * @param $queue AMQPQueue
 * @return bool
 * @throws MongoCursorException
 * @throws MongoCursorTimeoutException
 * @throws MongoException
 * @author: pengjch 2019-10-10 14:42
 */
public function rabbitMqMsgHandle( $envelope, $queue ){
    $json = $envelope->getBody();
    $data = CJSON::decode($json);
    if($data['className']){
        $class = new $data['className'];
    }else{
        $class = $this;
    }
    $method = $data['method'];
    if(!method_exists($class,$method)){
        echo '未定义'.$data['method'].'方法!'."\n";
        $queue->ack($envelope->getDeliveryTag());   //未定义的方法直接抛弃
    }else{
        if($class->$method($data)){
            //$queue->ack()。当工作者(worker)完成了任务,就发送一个响应。
            //当工作者(worker)挂掉这后,所有没有响应的消息都会重新发送。
            $queue->ack($envelope->getDeliveryTag());
        }else{
            $cacheKey = md5(json_encode($data));
            $retryTime = CommonUtils::getCache($cacheKey)?:0;
            if($retryTime < WK::RABBIT_MQ_QUEUE_RETRY_TIME){   //防止mq队列死循环崩溃   重新入列10次后抛弃此次任务
                $retryTime += 1;
                echo '重新进入列队'.$retryTime.'次!'."\n";
                CommonUtils::setCache($cacheKey,$retryTime,3600);
                $queue->nack($envelope->getDeliveryTag(),AMQP_REQUEUE);
            }else{
                echo "放弃当前数据进入Unacked,处理下一条消息"."\n";
                $queue->ack($envelope->getDeliveryTag()); //不能直接响应,响应则视为垃圾处理(垃圾处理)
            }
        }
    }
}


php rabbitMq增加心跳检测 -- heartbeat(转)


heartbeat通常用来检测通信的对端是否存活(未正常关闭socket连接而异常crash)。其基本原理是检测对应的socket连接上数据的收发是否正常,如果一段时间内没有收发数据,则向对端发送一个心跳检测包,如果一段时间内没有回应则认为心跳超时,即认为对端可能异常crash了。

rabbitmq也不例外,heatbeat在客户端和服务端之间用于检测对端是否正常,即客户端与服务端之间的tcp链接是否正常。

1. heartbeat检测时间间隔的设置

1). 服务端的设置

heartbeat检测时间间隔可在配置文件rabbitmq.config中增加配置项{heartbeat,Timeout}进行配置,其中Timeout指定时间间隔,单位为秒。

例如:

如果没有进行配置,默认的时间间隔为600秒(最新版本3.2.2修改为580秒)

在rabbit.app中有heartbeat的配置项。

2). 客户端的设置

根据AMQP协议,rabbitmq会通过connection.tune信令将heartbeat检测时间间隔告知客户端,客户端可以根据需要重新设置该值,并通过Connection.tune-ok信令将时间间隔再告诉给rabbitmq,rabbitmq会以客户端的时间作为该tcp连接上heartbeat检测的间隔时间。

这里要注意的是:如果时间间隔配置为0,则表示不启用heartbeat检测。

C客户端里:

AMQP_CALL amqp_login(amqp_connection_state_t state, char const *vhost,
                     int channel_max, int frame_max, int heartbeat,
                     amqp_sasl_method_enum sasl_method, ...);

参数heartbeat参数表示心跳频率,60则表示每60S发一次心跳包

如果启用了rabbitmq_management的话,从web控制台可以看到客户端的检测的时间间隔。